v
Зеркало из https://github.com/vlang/v
1module edwards25519
2
3import rand
4import encoding.binary
5import crypto.internal.subtle
6
7// A Scalar is an integer modulo
8//
9// l = 2^252 + 27742317777372353535851937790883648493
10//
11// which is the prime order of the edwards25519 group.
12//
13// This type works similarly to math/big.Int, and all arguments and
14// receivers are allowed to alias.
15//
16// The zero value is a valid zero element.
17struct Scalar {
18mut:
19// s is the Scalar value in little-endian. The value is always reduced
20// between operations.
21s [32]u8
22}
23
24pub const sc_zero = Scalar{
25s: [u8(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260, 0, 0, 0]!
27}
28
29pub const sc_one = Scalar{
30s: [u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310, 0, 0, 0]!
32}
33
34pub const sc_minus_one = Scalar{
35s: [u8(236), 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0,
360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]!
37}
38
39// new_scalar return new zero scalar
40pub fn new_scalar() Scalar {
41return Scalar{}
42}
43
44// add sets s = x + y mod l, and returns s.
45pub fn (mut s Scalar) add(x Scalar, y Scalar) Scalar {
46// s = 1 * x + y mod l
47sc_mul_add(mut s.s, sc_one.s, x.s, y.s)
48return s
49}
50
51// multiply_add sets s = x * y + z mod l, and returns s.
52pub fn (mut s Scalar) multiply_add(x Scalar, y Scalar, z Scalar) Scalar {
53sc_mul_add(mut s.s, x.s, y.s, z.s)
54return s
55}
56
57// subtract sets s = x - y mod l, and returns s.
58pub fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar {
59// s = -1 * y + x mod l
60sc_mul_add(mut s.s, sc_minus_one.s, y.s, x.s)
61return s
62}
63
64// negate sets s = -x mod l, and returns s.
65pub fn (mut s Scalar) negate(x Scalar) Scalar {
66// s = -1 * x + 0 mod l
67sc_mul_add(mut s.s, sc_minus_one.s, x.s, sc_zero.s)
68return s
69}
70
71// multiply sets s = x * y mod l, and returns s.
72pub fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar {
73// s = x * y + 0 mod l
74sc_mul_add(mut s.s, x.s, y.s, sc_zero.s)
75return s
76}
77
78// set sets s = x, and returns s.
79pub fn (mut s Scalar) set(x Scalar) Scalar {
80s = x
81return s
82}
83
84// set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly
85// distributed random bytes. If x is not of the right length, set_uniform_bytes
86// returns an error, and the receiver is unchanged.
87pub fn (mut s Scalar) set_uniform_bytes(x []u8) !Scalar {
88if x.len != 64 {
89return error('edwards25519: invalid set_uniform_bytes input length')
90}
91mut wide_bytes := []u8{len: 64}
92copy(mut wide_bytes, x)
93// for i, item in x {
94// wide_bytes[i] = item
95//}
96sc_reduce(mut s.s, mut wide_bytes)
97return s
98}
99
100// set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of
101// s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
102// returns an error, and the receiver is unchanged.
103pub fn (mut s Scalar) set_canonical_bytes(x []u8) !Scalar {
104if x.len != 32 {
105return error('invalid scalar length')
106}
107// mut bb := []u8{len:32}
108mut ss := Scalar{}
109for i, item in x {
110ss.s[i] = item
111}
112
113//_ := copy(mut ss.s[..], x) //its not working
114if !is_reduced(ss) {
115return error('invalid scalar encoding')
116}
117s.s = ss.s
118return s
119}
120
121// is_reduced returns whether the given scalar is reduced modulo l.
122fn is_reduced(s Scalar) bool {
123for i := s.s.len - 1; i >= 0; i-- {
124if s.s[i] > sc_minus_one.s[i] {
125return false
126}
127if s.s[i] < sc_minus_one.s[i] {
128return true
129}
130/*
131switch {
132case s.s[i] > sc_minus_one.s[i]:
133return false
134case s.s[i] < sc_minus_one.s[i]:
135return true
136}
137*/
138}
139return true
140}
141
142// set_bytes_with_clamping applies the buffer pruning described in RFC 8032,
143// Section 5.1.5 (also known as clamping) and sets s to the result. The input
144// must be 32 bytes, and it is not modified. If x is not of the right length,
145// `set_bytes_with_clamping` returns an error, and the receiver is unchanged.
146//
147// Note that since Scalar values are always reduced modulo the prime order of
148// the curve, the resulting value will not preserve any of the cofactor-clearing
149// properties that clamping is meant to provide. It will however work as
150// expected as long as it is applied to points on the prime order subgroup, like
151// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
152// irrelevant RFC 7748 clamping, but it is now required for compatibility.
153pub fn (mut s Scalar) set_bytes_with_clamping(x []u8) !Scalar {
154// The description above omits the purpose of the high bits of the clamping
155// for brevity, but those are also lost to reductions, and are also
156// irrelevant to edwards25519 as they protect against a specific
157// implementation bug that was once observed in a generic Montgomery ladder.
158if x.len != 32 {
159return error('edwards25519: invalid set_bytes_with_clamping input length')
160}
161
162mut wide_bytes := []u8{len: 64, cap: 64}
163copy(mut wide_bytes, x)
164// for i, item in x {
165// wide_bytes[i] = item
166//}
167wide_bytes[0] &= 248
168wide_bytes[31] &= 63
169wide_bytes[31] |= 64
170sc_reduce(mut s.s, mut wide_bytes)
171return s
172}
173
174// bytes returns the canonical 32-byte little-endian encoding of s.
175pub fn (mut s Scalar) bytes() []u8 {
176mut buf := []u8{len: 32}
177copy(mut buf, s.s[..])
178return buf
179}
180
181// equal returns 1 if s and t are equal, and 0 otherwise.
182pub fn (s Scalar) equal(t Scalar) int {
183return subtle.constant_time_compare(s.s[..], t.s[..])
184}
185
186// sc_mul_add and sc_reduce are ported from the public domain, “ref10”
187// implementation of ed25519 from SUPERCOP.
188fn load3(inp []u8) i64 {
189mut r := i64(inp[0])
190r |= i64(inp[1]) * 256 // << 8
191r |= i64(inp[2]) * 65536 // << 16
192return r
193}
194
195fn load4(inp []u8) i64 {
196mut r := i64(inp[0])
197r |= i64(inp[1]) * 256
198r |= i64(inp[2]) * 65536
199r |= i64(inp[3]) * 16777216
200return r
201}
202
203// Input:
204// a[0]+256*a[1]+...+256^31*a[31] = a
205// b[0]+256*b[1]+...+256^31*b[31] = b
206// c[0]+256*c[1]+...+256^31*c[31] = c
207//
208// Output:
209// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
210// where l = 2^252 + 27742317777372353535851937790883648493.
211fn sc_mul_add(mut s [32]u8, a [32]u8, b [32]u8, c [32]u8) {
212a0 := 2097151 & load3(a[..])
213a1 := 2097151 & (load4(a[2..]) >> 5)
214a2 := 2097151 & (load3(a[5..]) >> 2)
215a3 := 2097151 & (load4(a[7..]) >> 7)
216a4 := 2097151 & (load4(a[10..]) >> 4)
217a5 := 2097151 & (load3(a[13..]) >> 1)
218a6 := 2097151 & (load4(a[15..]) >> 6)
219a7 := 2097151 & (load3(a[18..]) >> 3)
220a8 := 2097151 & load3(a[21..])
221a9 := 2097151 & (load4(a[23..]) >> 5)
222a10 := 2097151 & (load3(a[26..]) >> 2)
223a11 := (load4(a[28..]) >> 7)
224b0 := 2097151 & load3(b[..])
225b1 := 2097151 & (load4(b[2..]) >> 5)
226b2 := 2097151 & (load3(b[5..]) >> 2)
227b3 := 2097151 & (load4(b[7..]) >> 7)
228b4 := 2097151 & (load4(b[10..]) >> 4)
229b5 := 2097151 & (load3(b[13..]) >> 1)
230b6 := 2097151 & (load4(b[15..]) >> 6)
231b7 := 2097151 & (load3(b[18..]) >> 3)
232b8 := 2097151 & load3(b[21..])
233b9 := 2097151 & (load4(b[23..]) >> 5)
234b10 := 2097151 & (load3(b[26..]) >> 2)
235b11 := (load4(b[28..]) >> 7)
236c0 := 2097151 & load3(c[..])
237c1 := 2097151 & (load4(c[2..]) >> 5)
238c2 := 2097151 & (load3(c[5..]) >> 2)
239c3 := 2097151 & (load4(c[7..]) >> 7)
240c4 := 2097151 & (load4(c[10..]) >> 4)
241c5 := 2097151 & (load3(c[13..]) >> 1)
242c6 := 2097151 & (load4(c[15..]) >> 6)
243c7 := 2097151 & (load3(c[18..]) >> 3)
244c8 := 2097151 & load3(c[21..])
245c9 := 2097151 & (load4(c[23..]) >> 5)
246c10 := 2097151 & (load3(c[26..]) >> 2)
247c11 := (load4(c[28..]) >> 7)
248
249mut carry := [23]i64{} // original one
250// mut carry := [23]u64{}
251
252mut s0 := c0 + a0 * b0
253mut s1 := c1 + a0 * b1 + a1 * b0
254mut s2 := c2 + a0 * b2 + a1 * b1 + a2 * b0
255mut s3 := c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0
256mut s4 := c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0
257mut s5 := c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0
258mut s6 := c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0
259mut s7 := c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0
260mut s8 := c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 +
261a8 * b0
262mut s9 := c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 +
263a8 * b1 + a9 * b0
264mut s10 := c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 +
265a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0
266mut s11 := c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 +
267a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0
268mut s12 := a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 +
269a9 * b3 + a10 * b2 + a11 * b1
270mut s13 := a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 +
271a10 * b3 + a11 * b2
272mut s14 := a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 +
273a11 * b3
274mut s15 := a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4
275mut s16 := a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5
276mut s17 := a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6
277mut s18 := a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7
278mut s19 := a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8
279mut s20 := a9 * b11 + a10 * b10 + a11 * b9
280mut s21 := a10 * b11 + a11 * b10
281mut s22 := a11 * b11
282
283mut s23 := i64(0) // original
284// mut s23 := u64(0)
285
286// carry[0] = (s0 + (1048576)) >> 21
287carry[0] = (s0 + (1048576)) >> 21
288s1 += carry[0]
289s0 -= carry[0] * 2097152
290carry[2] = (s2 + (1048576)) >> 21
291s3 += carry[2]
292s2 -= carry[2] * 2097152
293carry[4] = (s4 + (1048576)) >> 21
294s5 += carry[4]
295s4 -= carry[4] * 2097152
296carry[6] = (s6 + (1048576)) >> 21
297s7 += carry[6]
298s6 -= carry[6] * 2097152
299carry[8] = (s8 + (1048576)) >> 21
300s9 += carry[8]
301s8 -= carry[8] * 2097152
302carry[10] = (s10 + (1048576)) >> 21
303s11 += carry[10]
304s10 -= carry[10] * 2097152
305carry[12] = (s12 + (1048576)) >> 21
306s13 += carry[12]
307s12 -= carry[12] * 2097152
308carry[14] = (s14 + (1048576)) >> 21
309s15 += carry[14]
310s14 -= carry[14] * 2097152
311carry[16] = (s16 + (1048576)) >> 21
312s17 += carry[16]
313s16 -= carry[16] * 2097152
314carry[18] = (s18 + (1048576)) >> 21
315s19 += carry[18]
316s18 -= carry[18] * 2097152
317carry[20] = (s20 + (1048576)) >> 21
318s21 += carry[20]
319s20 -= carry[20] * 2097152
320carry[22] = (s22 + (1048576)) >> 21
321s23 += carry[22]
322s22 -= carry[22] * 2097152
323
324carry[1] = (s1 + (1048576)) >> 21
325s2 += carry[1]
326s1 -= carry[1] * 2097152
327carry[3] = (s3 + (1048576)) >> 21
328s4 += carry[3]
329s3 -= carry[3] * 2097152
330carry[5] = (s5 + (1048576)) >> 21
331s6 += carry[5]
332s5 -= carry[5] * 2097152
333carry[7] = (s7 + (1048576)) >> 21
334s8 += carry[7]
335s7 -= carry[7] * 2097152
336carry[9] = (s9 + (1048576)) >> 21
337s10 += carry[9]
338s9 -= carry[9] * 2097152
339carry[11] = (s11 + (1048576)) >> 21
340s12 += carry[11]
341s11 -= carry[11] * 2097152
342carry[13] = (s13 + (1048576)) >> 21
343s14 += carry[13]
344s13 -= carry[13] * 2097152
345carry[15] = (s15 + (1048576)) >> 21
346s16 += carry[15]
347s15 -= carry[15] * 2097152
348carry[17] = (s17 + (1048576)) >> 21
349s18 += carry[17]
350s17 -= carry[17] * 2097152
351carry[19] = (s19 + (1048576)) >> 21
352s20 += carry[19]
353s19 -= carry[19] * 2097152
354carry[21] = (s21 + (1048576)) >> 21
355s22 += carry[21]
356s21 -= carry[21] * 2097152
357
358s11 += s23 * 666643
359s12 += s23 * 470296
360s13 += s23 * 654183
361s14 -= s23 * 997805
362s15 += s23 * 136657
363s16 -= s23 * 683901
364s23 = 0
365
366s10 += s22 * 666643
367s11 += s22 * 470296
368s12 += s22 * 654183
369s13 -= s22 * 997805
370s14 += s22 * 136657
371s15 -= s22 * 683901
372s22 = 0
373
374s9 += s21 * 666643
375s10 += s21 * 470296
376s11 += s21 * 654183
377s12 -= s21 * 997805
378s13 += s21 * 136657
379s14 -= s21 * 683901
380s21 = 0
381
382s8 += s20 * 666643
383s9 += s20 * 470296
384s10 += s20 * 654183
385s11 -= s20 * 997805
386s12 += s20 * 136657
387s13 -= s20 * 683901
388s20 = 0
389
390s7 += s19 * 666643
391s8 += s19 * 470296
392s9 += s19 * 654183
393s10 -= s19 * 997805
394s11 += s19 * 136657
395s12 -= s19 * 683901
396s19 = 0
397
398s6 += s18 * 666643
399s7 += s18 * 470296
400s8 += s18 * 654183
401s9 -= s18 * 997805
402s10 += s18 * 136657
403s11 -= s18 * 683901
404s18 = 0
405
406carry[6] = (s6 + (1048576)) >> 21
407s7 += carry[6]
408s6 -= carry[6] * 2097152
409carry[8] = (s8 + (1048576)) >> 21
410s9 += carry[8]
411s8 -= carry[8] * 2097152
412carry[10] = (s10 + (1048576)) >> 21
413s11 += carry[10]
414s10 -= carry[10] * 2097152
415carry[12] = (s12 + (1048576)) >> 21
416s13 += carry[12]
417s12 -= carry[12] * 2097152
418carry[14] = (s14 + (1048576)) >> 21
419s15 += carry[14]
420s14 -= carry[14] * 2097152
421carry[16] = (s16 + (1048576)) >> 21
422s17 += carry[16]
423s16 -= carry[16] * 2097152
424
425carry[7] = (s7 + (1048576)) >> 21
426s8 += carry[7]
427s7 -= carry[7] * 2097152
428carry[9] = (s9 + (1048576)) >> 21
429s10 += carry[9]
430s9 -= carry[9] * 2097152
431carry[11] = (s11 + (1048576)) >> 21
432s12 += carry[11]
433s11 -= carry[11] * 2097152
434carry[13] = (s13 + (1048576)) >> 21
435s14 += carry[13]
436s13 -= carry[13] * 2097152
437carry[15] = (s15 + (1048576)) >> 21
438s16 += carry[15]
439s15 -= carry[15] * 2097152
440
441s5 += s17 * 666643
442s6 += s17 * 470296
443s7 += s17 * 654183
444s8 -= s17 * 997805
445s9 += s17 * 136657
446s10 -= s17 * 683901
447s17 = 0
448
449s4 += s16 * 666643
450s5 += s16 * 470296
451s6 += s16 * 654183
452s7 -= s16 * 997805
453s8 += s16 * 136657
454s9 -= s16 * 683901
455s16 = 0
456
457s3 += s15 * 666643
458s4 += s15 * 470296
459s5 += s15 * 654183
460s6 -= s15 * 997805
461s7 += s15 * 136657
462s8 -= s15 * 683901
463s15 = 0
464
465s2 += s14 * 666643
466s3 += s14 * 470296
467s4 += s14 * 654183
468s5 -= s14 * 997805
469s6 += s14 * 136657
470s7 -= s14 * 683901
471s14 = 0
472
473s1 += s13 * 666643
474s2 += s13 * 470296
475s3 += s13 * 654183
476s4 -= s13 * 997805
477s5 += s13 * 136657
478s6 -= s13 * 683901
479s13 = 0
480
481s0 += s12 * 666643
482s1 += s12 * 470296
483s2 += s12 * 654183
484s3 -= s12 * 997805
485s4 += s12 * 136657
486s5 -= s12 * 683901
487s12 = 0
488
489carry[0] = (s0 + (1048576)) >> 21
490s1 += carry[0]
491s0 -= carry[0] * 2097152
492carry[2] = (s2 + (1048576)) >> 21
493s3 += carry[2]
494s2 -= carry[2] * 2097152
495carry[4] = (s4 + (1048576)) >> 21
496s5 += carry[4]
497s4 -= carry[4] * 2097152
498carry[6] = (s6 + (1048576)) >> 21
499s7 += carry[6]
500s6 -= carry[6] * 2097152
501carry[8] = (s8 + (1048576)) >> 21
502s9 += carry[8]
503s8 -= carry[8] * 2097152
504carry[10] = (s10 + (1048576)) >> 21
505s11 += carry[10]
506s10 -= carry[10] * 2097152
507
508carry[1] = (s1 + (1048576)) >> 21
509s2 += carry[1]
510s1 -= carry[1] * 2097152
511carry[3] = (s3 + (1048576)) >> 21
512s4 += carry[3]
513s3 -= carry[3] * 2097152
514carry[5] = (s5 + (1048576)) >> 21
515s6 += carry[5]
516s5 -= carry[5] * 2097152
517carry[7] = (s7 + (1048576)) >> 21
518s8 += carry[7]
519s7 -= carry[7] * 2097152
520carry[9] = (s9 + (1048576)) >> 21
521s10 += carry[9]
522s9 -= carry[9] * 2097152
523carry[11] = (s11 + (1048576)) >> 21
524s12 += carry[11]
525s11 -= carry[11] * 2097152
526
527s0 += s12 * 666643
528s1 += s12 * 470296
529s2 += s12 * 654183
530s3 -= s12 * 997805
531s4 += s12 * 136657
532s5 -= s12 * 683901
533s12 = 0
534
535carry[0] = s0 >> 21
536s1 += carry[0]
537s0 -= carry[0] * 2097152
538carry[1] = s1 >> 21
539s2 += carry[1]
540s1 -= carry[1] * 2097152
541carry[2] = s2 >> 21
542s3 += carry[2]
543s2 -= carry[2] * 2097152
544carry[3] = s3 >> 21
545s4 += carry[3]
546s3 -= carry[3] * 2097152
547carry[4] = s4 >> 21
548s5 += carry[4]
549s4 -= carry[4] * 2097152
550carry[5] = s5 >> 21
551s6 += carry[5]
552s5 -= carry[5] * 2097152
553carry[6] = s6 >> 21
554s7 += carry[6]
555s6 -= carry[6] * 2097152
556carry[7] = s7 >> 21
557s8 += carry[7]
558s7 -= carry[7] * 2097152
559carry[8] = s8 >> 21
560s9 += carry[8]
561s8 -= carry[8] * 2097152
562carry[9] = s9 >> 21
563s10 += carry[9]
564s9 -= carry[9] * 2097152
565carry[10] = s10 >> 21
566s11 += carry[10]
567s10 -= carry[10] * 2097152
568carry[11] = s11 >> 21
569s12 += carry[11]
570s11 -= carry[11] * 2097152
571
572s0 += s12 * 666643
573s1 += s12 * 470296
574s2 += s12 * 654183
575s3 -= s12 * 997805
576s4 += s12 * 136657
577s5 -= s12 * 683901
578s12 = 0
579
580carry[0] = s0 >> 21
581s1 += carry[0]
582s0 -= carry[0] * 2097152
583carry[1] = s1 >> 21
584s2 += carry[1]
585s1 -= carry[1] * 2097152
586carry[2] = s2 >> 21
587s3 += carry[2]
588s2 -= carry[2] * 2097152
589carry[3] = s3 >> 21
590s4 += carry[3]
591s3 -= carry[3] * 2097152
592carry[4] = s4 >> 21
593s5 += carry[4]
594s4 -= carry[4] * 2097152
595carry[5] = s5 >> 21
596s6 += carry[5]
597s5 -= carry[5] * 2097152
598carry[6] = s6 >> 21
599s7 += carry[6]
600s6 -= carry[6] * 2097152
601carry[7] = s7 >> 21
602s8 += carry[7]
603s7 -= carry[7] * 2097152
604carry[8] = s8 >> 21
605s9 += carry[8]
606s8 -= carry[8] * 2097152
607carry[9] = s9 >> 21
608s10 += carry[9]
609s9 -= carry[9] * 2097152
610carry[10] = s10 >> 21
611s11 += carry[10]
612s10 -= carry[10] * 2097152
613
614s[0] = u8(s0 >> 0)
615s[1] = u8(s0 >> 8)
616s[2] = u8((s0 >> 16) | (s1 * 32))
617s[3] = u8(s1 >> 3)
618s[4] = u8(s1 >> 11)
619s[5] = u8((s1 >> 19) | (s2 * 4))
620s[6] = u8(s2 >> 6)
621s[7] = u8((s2 >> 14) | (s3 * 128))
622s[8] = u8(s3 >> 1)
623s[9] = u8(s3 >> 9)
624s[10] = u8((s3 >> 17) | (s4 * 16))
625s[11] = u8(s4 >> 4)
626s[12] = u8(s4 >> 12)
627s[13] = u8((s4 >> 20) | (s5 * 2))
628s[14] = u8(s5 >> 7)
629s[15] = u8((s5 >> 15) | (s6 * 64))
630s[16] = u8(s6 >> 2)
631s[17] = u8(s6 >> 10)
632s[18] = u8((s6 >> 18) | (s7 * 8))
633s[19] = u8(s7 >> 5)
634s[20] = u8(s7 >> 13)
635s[21] = u8(s8 >> 0)
636s[22] = u8(s8 >> 8)
637s[23] = u8((s8 >> 16) | (s9 * 32))
638s[24] = u8(s9 >> 3)
639s[25] = u8(s9 >> 11)
640s[26] = u8((s9 >> 19) | (s10 * 4))
641s[27] = u8(s10 >> 6)
642s[28] = u8((s10 >> 14) | (s11 * 128))
643s[29] = u8(s11 >> 1)
644s[30] = u8(s11 >> 9)
645s[31] = u8(s11 >> 17)
646}
647
648// Input:
649// s[0]+256*s[1]+...+256^63*s[63] = s
650//
651// Output:
652// s[0]+256*s[1]+...+256^31*s[31] = s mod l
653// where l = 2^252 + 27742317777372353535851937790883648493.
654fn sc_reduce(mut out [32]u8, mut s []u8) {
655assert out.len == 32
656assert s.len == 64
657mut s0 := 2097151 & load3(s[..])
658mut s1 := 2097151 & (load4(s[2..]) >> 5)
659mut s2 := 2097151 & (load3(s[5..]) >> 2)
660mut s3 := 2097151 & (load4(s[7..]) >> 7)
661mut s4 := 2097151 & (load4(s[10..]) >> 4)
662mut s5 := 2097151 & (load3(s[13..]) >> 1)
663mut s6 := 2097151 & (load4(s[15..]) >> 6)
664mut s7 := 2097151 & (load3(s[18..]) >> 3)
665mut s8 := 2097151 & load3(s[21..])
666mut s9 := 2097151 & (load4(s[23..]) >> 5)
667mut s10 := 2097151 & (load3(s[26..]) >> 2)
668mut s11 := 2097151 & (load4(s[28..]) >> 7)
669mut s12 := 2097151 & (load4(s[31..]) >> 4)
670mut s13 := 2097151 & (load3(s[34..]) >> 1)
671mut s14 := 2097151 & (load4(s[36..]) >> 6)
672mut s15 := 2097151 & (load3(s[39..]) >> 3)
673mut s16 := 2097151 & load3(s[42..])
674mut s17 := 2097151 & (load4(s[44..]) >> 5)
675mut s18 := 2097151 & (load3(s[47..]) >> 2)
676mut s19 := 2097151 & (load4(s[49..]) >> 7)
677mut s20 := 2097151 & (load4(s[52..]) >> 4)
678mut s21 := 2097151 & (load3(s[55..]) >> 1)
679mut s22 := 2097151 & (load4(s[57..]) >> 6)
680mut s23 := (load4(s[60..]) >> 3)
681
682s11 += s23 * 666643
683s12 += s23 * 470296
684s13 += s23 * 654183
685s14 -= s23 * 997805
686s15 += s23 * 136657
687s16 -= s23 * 683901
688s23 = 0
689
690s10 += s22 * 666643
691s11 += s22 * 470296
692s12 += s22 * 654183
693s13 -= s22 * 997805
694s14 += s22 * 136657
695s15 -= s22 * 683901
696s22 = 0
697
698s9 += s21 * 666643
699s10 += s21 * 470296
700s11 += s21 * 654183
701s12 -= s21 * 997805
702s13 += s21 * 136657
703s14 -= s21 * 683901
704s21 = 0
705
706s8 += s20 * 666643
707s9 += s20 * 470296
708s10 += s20 * 654183
709s11 -= s20 * 997805
710s12 += s20 * 136657
711s13 -= s20 * 683901
712s20 = 0
713
714s7 += s19 * 666643
715s8 += s19 * 470296
716s9 += s19 * 654183
717s10 -= s19 * 997805
718s11 += s19 * 136657
719s12 -= s19 * 683901
720s19 = 0
721
722s6 += s18 * 666643
723s7 += s18 * 470296
724s8 += s18 * 654183
725s9 -= s18 * 997805
726s10 += s18 * 136657
727s11 -= s18 * 683901
728s18 = 0
729
730mut carry := [17]i64{} // original one
731// mut carry := [17]u64{}
732
733carry[6] = (s6 + (1048576)) >> 21
734s7 += carry[6]
735s6 -= carry[6] * 2097152
736carry[8] = (s8 + (1048576)) >> 21
737s9 += carry[8]
738s8 -= carry[8] * 2097152
739carry[10] = (s10 + (1048576)) >> 21
740s11 += carry[10]
741s10 -= carry[10] * 2097152
742carry[12] = (s12 + (1048576)) >> 21
743s13 += carry[12]
744s12 -= carry[12] * 2097152
745carry[14] = (s14 + (1048576)) >> 21
746s15 += carry[14]
747s14 -= carry[14] * 2097152
748carry[16] = (s16 + (1048576)) >> 21
749s17 += carry[16]
750s16 -= carry[16] * 2097152
751
752carry[7] = (s7 + (1048576)) >> 21
753s8 += carry[7]
754s7 -= carry[7] * 2097152
755carry[9] = (s9 + (1048576)) >> 21
756s10 += carry[9]
757s9 -= carry[9] * 2097152
758carry[11] = (s11 + (1048576)) >> 21
759s12 += carry[11]
760s11 -= carry[11] * 2097152
761carry[13] = (s13 + (1048576)) >> 21
762s14 += carry[13]
763s13 -= carry[13] * 2097152
764carry[15] = (s15 + (1048576)) >> 21
765s16 += carry[15]
766s15 -= carry[15] * 2097152
767
768s5 += s17 * 666643
769s6 += s17 * 470296
770s7 += s17 * 654183
771s8 -= s17 * 997805
772s9 += s17 * 136657
773s10 -= s17 * 683901
774s17 = 0
775
776s4 += s16 * 666643
777s5 += s16 * 470296
778s6 += s16 * 654183
779s7 -= s16 * 997805
780s8 += s16 * 136657
781s9 -= s16 * 683901
782s16 = 0
783
784s3 += s15 * 666643
785s4 += s15 * 470296
786s5 += s15 * 654183
787s6 -= s15 * 997805
788s7 += s15 * 136657
789s8 -= s15 * 683901
790s15 = 0
791
792s2 += s14 * 666643
793s3 += s14 * 470296
794s4 += s14 * 654183
795s5 -= s14 * 997805
796s6 += s14 * 136657
797s7 -= s14 * 683901
798s14 = 0
799
800s1 += s13 * 666643
801s2 += s13 * 470296
802s3 += s13 * 654183
803s4 -= s13 * 997805
804s5 += s13 * 136657
805s6 -= s13 * 683901
806s13 = 0
807
808s0 += s12 * 666643
809s1 += s12 * 470296
810s2 += s12 * 654183
811s3 -= s12 * 997805
812s4 += s12 * 136657
813s5 -= s12 * 683901
814s12 = 0
815
816carry[0] = (s0 + (1048576)) >> 21
817s1 += carry[0]
818s0 -= carry[0] * 2097152
819carry[2] = (s2 + (1048576)) >> 21
820s3 += carry[2]
821s2 -= carry[2] * 2097152
822carry[4] = (s4 + (1048576)) >> 21
823s5 += carry[4]
824s4 -= carry[4] * 2097152
825carry[6] = (s6 + (1048576)) >> 21
826s7 += carry[6]
827s6 -= carry[6] * 2097152
828carry[8] = (s8 + (1048576)) >> 21
829s9 += carry[8]
830s8 -= carry[8] * 2097152
831carry[10] = (s10 + (1048576)) >> 21
832s11 += carry[10]
833s10 -= carry[10] * 2097152
834
835carry[1] = (s1 + (1048576)) >> 21
836s2 += carry[1]
837s1 -= carry[1] * 2097152
838carry[3] = (s3 + (1048576)) >> 21
839s4 += carry[3]
840s3 -= carry[3] * 2097152
841carry[5] = (s5 + (1048576)) >> 21
842s6 += carry[5]
843s5 -= carry[5] * 2097152
844carry[7] = (s7 + (1048576)) >> 21
845s8 += carry[7]
846s7 -= carry[7] * 2097152
847carry[9] = (s9 + (1048576)) >> 21
848s10 += carry[9]
849s9 -= carry[9] * 2097152
850carry[11] = (s11 + (1048576)) >> 21
851s12 += carry[11]
852s11 -= carry[11] * 2097152
853
854s0 += s12 * 666643
855s1 += s12 * 470296
856s2 += s12 * 654183
857s3 -= s12 * 997805
858s4 += s12 * 136657
859s5 -= s12 * 683901
860s12 = 0
861
862carry[0] = s0 >> 21
863s1 += carry[0]
864s0 -= carry[0] * 2097152
865carry[1] = s1 >> 21
866s2 += carry[1]
867s1 -= carry[1] * 2097152
868carry[2] = s2 >> 21
869s3 += carry[2]
870s2 -= carry[2] * 2097152
871carry[3] = s3 >> 21
872s4 += carry[3]
873s3 -= carry[3] * 2097152
874carry[4] = s4 >> 21
875s5 += carry[4]
876s4 -= carry[4] * 2097152
877carry[5] = s5 >> 21
878s6 += carry[5]
879s5 -= carry[5] * 2097152
880carry[6] = s6 >> 21
881s7 += carry[6]
882s6 -= carry[6] * 2097152
883carry[7] = s7 >> 21
884s8 += carry[7]
885s7 -= carry[7] * 2097152
886carry[8] = s8 >> 21
887s9 += carry[8]
888s8 -= carry[8] * 2097152
889carry[9] = s9 >> 21
890s10 += carry[9]
891s9 -= carry[9] * 2097152
892carry[10] = s10 >> 21
893s11 += carry[10]
894s10 -= carry[10] * 2097152
895carry[11] = s11 >> 21
896s12 += carry[11]
897s11 -= carry[11] * 2097152
898
899s0 += s12 * 666643
900s1 += s12 * 470296
901s2 += s12 * 654183
902s3 -= s12 * 997805
903s4 += s12 * 136657
904s5 -= s12 * 683901
905s12 = 0
906
907carry[0] = s0 >> 21
908s1 += carry[0]
909s0 -= carry[0] * 2097152
910carry[1] = s1 >> 21
911s2 += carry[1]
912s1 -= carry[1] * 2097152
913carry[2] = s2 >> 21
914s3 += carry[2]
915s2 -= carry[2] * 2097152
916carry[3] = s3 >> 21
917s4 += carry[3]
918s3 -= carry[3] * 2097152
919carry[4] = s4 >> 21
920s5 += carry[4]
921s4 -= carry[4] * 2097152
922carry[5] = s5 >> 21
923s6 += carry[5]
924s5 -= carry[5] * 2097152
925carry[6] = s6 >> 21
926s7 += carry[6]
927s6 -= carry[6] * 2097152
928carry[7] = s7 >> 21
929s8 += carry[7]
930s7 -= carry[7] * 2097152
931carry[8] = s8 >> 21
932s9 += carry[8]
933s8 -= carry[8] * 2097152
934carry[9] = s9 >> 21
935s10 += carry[9]
936s9 -= carry[9] * 2097152
937carry[10] = s10 >> 21
938s11 += carry[10]
939s10 -= carry[10] * 2097152
940
941out[0] = u8(s0 >> 0)
942out[1] = u8(s0 >> 8)
943out[2] = u8((s0 >> 16) | (s1 * 32))
944out[3] = u8(s1 >> 3)
945out[4] = u8(s1 >> 11)
946out[5] = u8((s1 >> 19) | (s2 * 4))
947out[6] = u8(s2 >> 6)
948out[7] = u8((s2 >> 14) | (s3 * 128))
949out[8] = u8(s3 >> 1)
950out[9] = u8(s3 >> 9)
951out[10] = u8((s3 >> 17) | (s4 * 16))
952out[11] = u8(s4 >> 4)
953out[12] = u8(s4 >> 12)
954out[13] = u8((s4 >> 20) | (s5 * 2))
955out[14] = u8(s5 >> 7)
956out[15] = u8((s5 >> 15) | (s6 * 64))
957out[16] = u8(s6 >> 2)
958out[17] = u8(s6 >> 10)
959out[18] = u8((s6 >> 18) | (s7 * 8))
960out[19] = u8(s7 >> 5)
961out[20] = u8(s7 >> 13)
962out[21] = u8(s8 >> 0)
963out[22] = u8(s8 >> 8)
964out[23] = u8((s8 >> 16) | (s9 * 32))
965out[24] = u8(s9 >> 3)
966out[25] = u8(s9 >> 11)
967out[26] = u8((s9 >> 19) | (s10 * 4))
968out[27] = u8(s10 >> 6)
969out[28] = u8((s10 >> 14) | (s11 * 128))
970out[29] = u8(s11 >> 1)
971out[30] = u8(s11 >> 9)
972out[31] = u8(s11 >> 17)
973}
974
975// non_adjacent_form computes a width-w non-adjacent form for this scalar.
976//
977// w must be between 2 and 8, or non_adjacent_form will panic.
978pub fn (mut s Scalar) non_adjacent_form(w u32) []i8 {
979// This implementation is adapted from the one
980// in curve25519-dalek and is documented there:
981// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
982if s.s[31] > 127 {
983panic('scalar has high bit set illegally')
984}
985if w < 2 {
986panic('w must be at least 2 by the definition of NAF')
987} else if w > 8 {
988panic('NAF digits must fit in i8')
989}
990
991mut naf := []i8{len: 256}
992mut digits := [5]u64{}
993
994for i := 0; i < 4; i++ {
995digits[i] = binary.little_endian_u64(s.s[i * 8..])
996}
997
998width := u64(1 << w)
999window_mask := u64(width - 1)
1000
1001mut pos := u32(0)
1002mut carry := u64(0)
1003for pos < 256 {
1004idx_64 := pos / 64
1005idx_bit := pos % 64
1006mut bitbuf := u64(0)
1007if idx_bit < 64 - w {
1008// This window's bits are contained in a single u64
1009bitbuf = digits[idx_64] >> idx_bit
1010} else {
1011// Combine the current 64 bits with bits from the next 64
1012bitbuf = (digits[idx_64] >> idx_bit) | (digits[1 + idx_64] << (64 - idx_bit))
1013}
1014
1015// Add carry into the current window
1016window := carry + (bitbuf & window_mask)
1017
1018if window & 1 == 0 {
1019// If the window value is even, preserve the carry and continue.
1020// Why is the carry preserved?
1021// If carry == 0 and window & 1 == 0,
1022// then the next carry should be 0
1023// If carry == 1 and window & 1 == 0,
1024// then bit_buf & 1 == 1 so the next carry should be 1
1025pos += 1
1026continue
1027}
1028
1029if window < width / 2 {
1030carry = 0
1031naf[pos] = i8(window)
1032} else {
1033carry = 1
1034naf[pos] = i8(window) - i8(width)
1035}
1036
1037pos += w
1038}
1039return naf
1040}
1041
1042fn (mut s Scalar) signed_radix16() []i8 {
1043if s.s[31] > 127 {
1044panic('scalar has high bit set illegally')
1045}
1046
1047mut digits := []i8{len: 64}
1048
1049// Compute unsigned radix-16 digits:
1050for i := 0; i < 32; i++ {
1051digits[2 * i] = i8(s.s[i] & 15)
1052digits[2 * i + 1] = i8((s.s[i] >> 4) & 15)
1053}
1054
1055// Recenter coefficients:
1056for i := 0; i < 63; i++ {
1057mut carry := (digits[i] + 8) >> 4
1058
1059// digits[i] -= unsafe { carry * 16 } // original one
1060digits[i] -= unsafe { carry * 16 } // carry * 16 == carry *
1061
1062digits[i + 1] += carry
1063}
1064
1065return digits
1066}
1067
1068// utility function
1069// generate returns a valid (reduced modulo l) Scalar with a distribution
1070// weighted towards high, low, and edge values.
1071fn generate_scalar(size int) !Scalar {
1072/*
1073s := scZero
1074diceRoll := rand.Intn(100)
1075switch {
1076case diceRoll == 0:
1077case diceRoll == 1:
1078s = scOne
1079case diceRoll == 2:
1080s = scMinusOne
1081case diceRoll < 5:
1082// Generate a low scalar in [0, 2^125).
1083rand.Read(s.s[:16])
1084s.s[15] &= (1 * 32) - 1
1085case diceRoll < 10:
1086// Generate a high scalar in [2^252, 2^252 + 2^124).
1087s.s[31] = 1 * 16
1088rand.Read(s.s[:16])
1089s.s[15] &= (1 * 16) - 1
1090default:
1091// Generate a valid scalar in [0, l) by returning [0, 2^252) which has a
1092// negligibly different distribution (the former has a 2^-127.6 chance
1093// of being out of the latter range).
1094rand.Read(s.s[:])
1095s.s[31] &= (1 * 16) - 1
1096}
1097return reflect.ValueOf(s)
1098*/
1099mut s := sc_zero
1100diceroll := rand.intn(100) or { 0 }
1101match true {
1102/*
1103case diceroll == 0:
1104case diceroll == 1:
1105*/
1106diceroll == 0 || diceroll == 1 {
1107s = sc_one
1108}
1109diceroll == 2 {
1110s = sc_minus_one
1111}
1112diceroll < 5 {
1113// rand.Read(s.s[:16]) // read random bytes and fill buf
1114// using builtin rand.read([]buf)
1115rand.read(mut s.s[..16])
1116// buf := rand.read(s.s[..16].len)!
1117// copy(mut s.s[..16], buf)
1118
1119/*
1120for i, item in buf {
1121s.s[i] = item
1122}
1123*/
1124s.s[15] &= (1 * 32) - 1
1125// generate a low scalar in [0, 2^125).
1126}
1127diceroll < 10 {
1128// generate a high scalar in [2^252, 2^252 + 2^124).
1129s.s[31] = 1 * 16
1130// Read generates len(p) random bytes and writes them into p
1131// rand.Read(s.s[:16])
1132rand.read(mut s.s[..16])
1133// buf := rand.read(s.s[..16].len)!
1134// copy(mut s.s[..16], buf)
1135
1136/*
1137for i, item in buf {
1138s.s[i] = item
1139}
1140*/
1141s.s[15] &= (1 * 16) - 1
1142}
1143else {
1144// generate a valid scalar in [0, l) by returning [0, 2^252) which has a
1145// negligibly different distribution (the former has a 2^-127.6 chance
1146// of being out of the latter range).
1147// rand.Read(s.s[:])
1148rand.read(mut s.s[..])
1149// buf := crand.read(s.s.len)!
1150// copy(mut s.s[..], buf)
1151
1152/*
1153for i, item in buf {
1154s.s[i] = item
1155}
1156*/
1157s.s[31] &= (1 * 16) - 1
1158}
1159}
1160return s
1161}
1162
1163type NotZeroScalar = Scalar
1164
1165fn generate_notzero_scalar(size int) !NotZeroScalar {
1166mut s := Scalar{}
1167for s == sc_zero {
1168s = generate_scalar(size)!
1169}
1170return NotZeroScalar(s)
1171}
1172