-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasics.go
140 lines (106 loc) · 2.34 KB
/
basics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package constbn
// Base represents the numerical type used for representing internal numbers
type Base uint32
// constant time primitive implementations. the ctl argument has to be Base(0) or Base(1)
func not(ctl Base) Base {
return ctl ^ one
}
// mux returns x if ctl is true, y if it's false
func mux(ctl, x, y Base) Base {
return y ^ (-ctl & (x ^ y))
}
func eq(x, y Base) Base {
q := x ^ y
return not((q | -q) >> 31)
}
func neq(x, y Base) Base {
q := x ^ y
return (q | -q) >> 31
}
// gt returns 1 if x > y, 0 otherwise
func gt(x, y Base) Base {
z := y - x
return (z ^ ((x ^ y) & (x ^ z))) >> 31
}
func ge(x, y Base) Base {
return not(gt(y, x))
}
func lt(x, y Base) Base {
return gt(y, x)
}
// func le(x, y Base) Base {
// return not(gt(x, y))
// }
func ccopy(ctl Base, dst, src []Base, len Base) {
for i := zero; i < len; i++ {
x := src[i]
y := dst[i]
dst[i] = mux(ctl, x, y)
}
}
const zero = Base(0)
const one = Base(1)
func bitLen(x Base) Base {
k := neq(x, zero)
c := gt(x, Base(0xFFFF))
x = mux(c, x>>16, x)
k += c << 4
c = gt(x, Base(0x00FF))
x = mux(c, x>>8, x)
k += c << 3
c = gt(x, Base(0x000F))
x = mux(c, x>>4, x)
k += c << 2
c = gt(x, Base(0x0003))
x = mux(c, x>>2, x)
k += c << 1
k += gt(x, Base(0x0001))
return k
}
// func min(x, y Base) Base {
// return mux(gt(x, y), y, x)
// }
// func max(x, y Base) Base {
// return mux(gt(x, y), x, y)
// }
func mul31(x, y Base) uint64 {
return uint64(x) * uint64(y)
}
func zeroes(len Base) []Base {
return make([]Base, len)
}
func zeroesBytes(len int) []byte {
return make([]byte, len)
}
/*
* Zeroize an integer. The announced bit length is set to the provided
* value, and the corresponding words are set to 0. The ENCODED bit length
* is expected here.
*/
func zeroize(x []Base, bitlen Base) {
x[0] = bitlen
toZero := (bitlen + 31) >> 5
copy(x[1:], zeroes(toZero))
}
func zeroizeBytes(x []byte) {
copy(x, zeroesBytes(len(x)))
}
const mask31 = Base(0x7FFFFFFF)
func enc32be(dst []byte, x Base) {
dst[0] = byte(x >> 24)
dst[1] = byte(x >> 16)
dst[2] = byte(x >> 8)
dst[3] = byte(x)
}
// func byteLen(a []Base) Base {
// return BaseLen(a) << 2
// }
func baseLen(a []Base) Base {
return (a[0] + 31) >> 5
}
// func byteLenWithHeader(a []Base) Base {
// return baseLenWithHeader(a) << 2
// }
func baseLenWithHeader(a []Base) Base {
return (a[0] + 63) >> 5
}