1174 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			1174 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			V
		
	
	
| module edwards25519
 | |
| 
 | |
| import rand
 | |
| import encoding.binary
 | |
| import crypto.internal.subtle
 | |
| 
 | |
| // A Scalar is an integer modulo
 | |
| //
 | |
| //     l = 2^252 + 27742317777372353535851937790883648493
 | |
| //
 | |
| // which is the prime order of the edwards25519 group.
 | |
| //
 | |
| // This type works similarly to math/big.Int, and all arguments and
 | |
| // receivers are allowed to alias.
 | |
| //
 | |
| // The zero value is a valid zero element.
 | |
| struct Scalar {
 | |
| mut:
 | |
| 	// s is the Scalar value in little-endian. The value is always reduced
 | |
| 	// between operations.
 | |
| 	s [32]byte
 | |
| }
 | |
| 
 | |
| pub const (
 | |
| 	sc_zero = Scalar{
 | |
| 		s: [byte(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, 0, 0, 0, 0]!
 | |
| 	}
 | |
| 
 | |
| 	sc_one = Scalar{
 | |
| 		s: [byte(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, 0, 0, 0, 0]!
 | |
| 	}
 | |
| 
 | |
| 	sc_minus_one = Scalar{
 | |
| 		s: [byte(236), 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0,
 | |
| 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]!
 | |
| 	}
 | |
| )
 | |
| 
 | |
| // new_scalar return new zero scalar
 | |
| pub fn new_scalar() Scalar {
 | |
| 	return Scalar{}
 | |
| }
 | |
| 
 | |
| // add sets s = x + y mod l, and returns s.
 | |
| pub fn (mut s Scalar) add(x Scalar, y Scalar) Scalar {
 | |
| 	// s = 1 * x + y mod l
 | |
| 	sc_mul_add(mut s.s, edwards25519.sc_one.s, x.s, y.s)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // multiply_add sets s = x * y + z mod l, and returns s.
 | |
| pub fn (mut s Scalar) multiply_add(x Scalar, y Scalar, z Scalar) Scalar {
 | |
| 	sc_mul_add(mut s.s, x.s, y.s, z.s)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // subtract sets s = x - y mod l, and returns s.
 | |
| pub fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar {
 | |
| 	// s = -1 * y + x mod l
 | |
| 	sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, y.s, x.s)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // negate sets s = -x mod l, and returns s.
 | |
| pub fn (mut s Scalar) negate(x Scalar) Scalar {
 | |
| 	// s = -1 * x + 0 mod l
 | |
| 	sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, x.s, edwards25519.sc_zero.s)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // multiply sets s = x * y mod l, and returns s.
 | |
| pub fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar {
 | |
| 	// s = x * y + 0 mod l
 | |
| 	sc_mul_add(mut s.s, x.s, y.s, edwards25519.sc_zero.s)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // set sets s = x, and returns s.
 | |
| pub fn (mut s Scalar) set(x Scalar) Scalar {
 | |
| 	s = x
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly
 | |
| // distributed random bytes. If x is not of the right length, set_uniform_bytes
 | |
| // returns an error, and the receiver is unchanged.
 | |
| pub fn (mut s Scalar) set_uniform_bytes(x []byte) ?Scalar {
 | |
| 	if x.len != 64 {
 | |
| 		return error('edwards25519: invalid set_uniform_bytes input length')
 | |
| 	}
 | |
| 	mut wide_bytes := []byte{len: 64}
 | |
| 	copy(mut wide_bytes, x)
 | |
| 	// for i, item in x {
 | |
| 	//	wide_bytes[i] = item
 | |
| 	//}
 | |
| 	sc_reduce(mut s.s, mut wide_bytes)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of
 | |
| // s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
 | |
| // returns an error, and the receiver is unchanged.
 | |
| pub fn (mut s Scalar) set_canonical_bytes(x []byte) ?Scalar {
 | |
| 	if x.len != 32 {
 | |
| 		return error('invalid scalar length')
 | |
| 	}
 | |
| 	// mut bb := []byte{len:32}
 | |
| 	mut ss := Scalar{}
 | |
| 	for i, item in x {
 | |
| 		ss.s[i] = item
 | |
| 	}
 | |
| 
 | |
| 	//_ := copy(mut ss.s[..], x) //its not working
 | |
| 	if !is_reduced(ss) {
 | |
| 		return error('invalid scalar encoding')
 | |
| 	}
 | |
| 	s.s = ss.s
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // is_reduced returns whether the given scalar is reduced modulo l.
 | |
| fn is_reduced(s Scalar) bool {
 | |
| 	for i := s.s.len - 1; i >= 0; i-- {
 | |
| 		if s.s[i] > edwards25519.sc_minus_one.s[i] {
 | |
| 			return false
 | |
| 		}
 | |
| 		if s.s[i] < edwards25519.sc_minus_one.s[i] {
 | |
| 			return true
 | |
| 		}
 | |
| 		/*
 | |
| 		switch {
 | |
| 		case s.s[i] > sc_minus_one.s[i]:
 | |
| 			return false
 | |
| 		case s.s[i] < sc_minus_one.s[i]:
 | |
| 			return true
 | |
| 		}
 | |
| 		*/
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // set_bytes_with_clamping applies the buffer pruning described in RFC 8032,
 | |
| // Section 5.1.5 (also known as clamping) and sets s to the result. The input
 | |
| // must be 32 bytes, and it is not modified. If x is not of the right length,
 | |
| // `set_bytes_with_clamping` returns an error, and the receiver is unchanged.
 | |
| //
 | |
| // Note that since Scalar values are always reduced modulo the prime order of
 | |
| // the curve, the resulting value will not preserve any of the cofactor-clearing
 | |
| // properties that clamping is meant to provide. It will however work as
 | |
| // expected as long as it is applied to points on the prime order subgroup, like
 | |
| // in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
 | |
| // irrelevant RFC 7748 clamping, but it is now required for compatibility.
 | |
| pub fn (mut s Scalar) set_bytes_with_clamping(x []byte) ?Scalar {
 | |
| 	// The description above omits the purpose of the high bits of the clamping
 | |
| 	// for brevity, but those are also lost to reductions, and are also
 | |
| 	// irrelevant to edwards25519 as they protect against a specific
 | |
| 	// implementation bug that was once observed in a generic Montgomery ladder.
 | |
| 	if x.len != 32 {
 | |
| 		return error('edwards25519: invalid set_bytes_with_clamping input length')
 | |
| 	}
 | |
| 
 | |
| 	mut wide_bytes := []byte{len: 64, cap: 64}
 | |
| 	copy(mut wide_bytes, x)
 | |
| 	// for i, item in x {
 | |
| 	//	wide_bytes[i] = item
 | |
| 	//}
 | |
| 	wide_bytes[0] &= 248
 | |
| 	wide_bytes[31] &= 63
 | |
| 	wide_bytes[31] |= 64
 | |
| 	sc_reduce(mut s.s, mut wide_bytes)
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // bytes returns the canonical 32-byte little-endian encoding of s.
 | |
| pub fn (mut s Scalar) bytes() []byte {
 | |
| 	mut buf := []byte{len: 32}
 | |
| 	copy(mut buf, s.s[..])
 | |
| 	return buf
 | |
| }
 | |
| 
 | |
| // equal returns 1 if s and t are equal, and 0 otherwise.
 | |
| pub fn (s Scalar) equal(t Scalar) int {
 | |
| 	return subtle.constant_time_compare(s.s[..], t.s[..])
 | |
| }
 | |
| 
 | |
| // sc_mul_add and sc_reduce are ported from the public domain, “ref10”
 | |
| // implementation of ed25519 from SUPERCOP.
 | |
| fn load3(inp []byte) i64 {
 | |
| 	mut r := i64(inp[0])
 | |
| 	r |= i64(inp[1]) * 256 // << 8
 | |
| 	r |= i64(inp[2]) * 65536 // << 16
 | |
| 	return r
 | |
| }
 | |
| 
 | |
| fn load4(inp []byte) i64 {
 | |
| 	mut r := i64(inp[0])
 | |
| 	r |= i64(inp[1]) * 256
 | |
| 	r |= i64(inp[2]) * 65536
 | |
| 	r |= i64(inp[3]) * 16777216
 | |
| 	return r
 | |
| }
 | |
| 
 | |
| // Input:
 | |
| //   a[0]+256*a[1]+...+256^31*a[31] = a
 | |
| //   b[0]+256*b[1]+...+256^31*b[31] = b
 | |
| //   c[0]+256*c[1]+...+256^31*c[31] = c
 | |
| //
 | |
| // Output:
 | |
| //   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
 | |
| //   where l = 2^252 + 27742317777372353535851937790883648493.
 | |
| fn sc_mul_add(mut s [32]byte, a [32]byte, b [32]byte, c [32]byte) {
 | |
| 	a0 := 2097151 & load3(a[..])
 | |
| 	a1 := 2097151 & (load4(a[2..]) >> 5)
 | |
| 	a2 := 2097151 & (load3(a[5..]) >> 2)
 | |
| 	a3 := 2097151 & (load4(a[7..]) >> 7)
 | |
| 	a4 := 2097151 & (load4(a[10..]) >> 4)
 | |
| 	a5 := 2097151 & (load3(a[13..]) >> 1)
 | |
| 	a6 := 2097151 & (load4(a[15..]) >> 6)
 | |
| 	a7 := 2097151 & (load3(a[18..]) >> 3)
 | |
| 	a8 := 2097151 & load3(a[21..])
 | |
| 	a9 := 2097151 & (load4(a[23..]) >> 5)
 | |
| 	a10 := 2097151 & (load3(a[26..]) >> 2)
 | |
| 	a11 := (load4(a[28..]) >> 7)
 | |
| 	b0 := 2097151 & load3(b[..])
 | |
| 	b1 := 2097151 & (load4(b[2..]) >> 5)
 | |
| 	b2 := 2097151 & (load3(b[5..]) >> 2)
 | |
| 	b3 := 2097151 & (load4(b[7..]) >> 7)
 | |
| 	b4 := 2097151 & (load4(b[10..]) >> 4)
 | |
| 	b5 := 2097151 & (load3(b[13..]) >> 1)
 | |
| 	b6 := 2097151 & (load4(b[15..]) >> 6)
 | |
| 	b7 := 2097151 & (load3(b[18..]) >> 3)
 | |
| 	b8 := 2097151 & load3(b[21..])
 | |
| 	b9 := 2097151 & (load4(b[23..]) >> 5)
 | |
| 	b10 := 2097151 & (load3(b[26..]) >> 2)
 | |
| 	b11 := (load4(b[28..]) >> 7)
 | |
| 	c0 := 2097151 & load3(c[..])
 | |
| 	c1 := 2097151 & (load4(c[2..]) >> 5)
 | |
| 	c2 := 2097151 & (load3(c[5..]) >> 2)
 | |
| 	c3 := 2097151 & (load4(c[7..]) >> 7)
 | |
| 	c4 := 2097151 & (load4(c[10..]) >> 4)
 | |
| 	c5 := 2097151 & (load3(c[13..]) >> 1)
 | |
| 	c6 := 2097151 & (load4(c[15..]) >> 6)
 | |
| 	c7 := 2097151 & (load3(c[18..]) >> 3)
 | |
| 	c8 := 2097151 & load3(c[21..])
 | |
| 	c9 := 2097151 & (load4(c[23..]) >> 5)
 | |
| 	c10 := 2097151 & (load3(c[26..]) >> 2)
 | |
| 	c11 := (load4(c[28..]) >> 7)
 | |
| 
 | |
| 	mut carry := [23]i64{} // original one
 | |
| 	// mut carry := [23]u64{}
 | |
| 
 | |
| 	mut s0 := c0 + a0 * b0
 | |
| 	mut s1 := c1 + a0 * b1 + a1 * b0
 | |
| 	mut s2 := c2 + a0 * b2 + a1 * b1 + a2 * b0
 | |
| 	mut s3 := c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0
 | |
| 	mut s4 := c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0
 | |
| 	mut s5 := c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0
 | |
| 	mut s6 := c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0
 | |
| 	mut s7 := c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0
 | |
| 	mut s8 := c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 +
 | |
| 		a8 * b0
 | |
| 	mut s9 := c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 +
 | |
| 		a8 * b1 + a9 * b0
 | |
| 	mut s10 := c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 +
 | |
| 		a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0
 | |
| 	mut s11 := c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 +
 | |
| 		a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0
 | |
| 	mut s12 := a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 +
 | |
| 		a9 * b3 + a10 * b2 + a11 * b1
 | |
| 	mut s13 := a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 +
 | |
| 		a10 * b3 + a11 * b2
 | |
| 	mut s14 := a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 +
 | |
| 		a11 * b3
 | |
| 	mut s15 := a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4
 | |
| 	mut s16 := a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5
 | |
| 	mut s17 := a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6
 | |
| 	mut s18 := a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7
 | |
| 	mut s19 := a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8
 | |
| 	mut s20 := a9 * b11 + a10 * b10 + a11 * b9
 | |
| 	mut s21 := a10 * b11 + a11 * b10
 | |
| 	mut s22 := a11 * b11
 | |
| 
 | |
| 	mut s23 := i64(0) // original
 | |
| 	// mut s23 := u64(0)
 | |
| 
 | |
| 	// carry[0] = (s0 + (1048576)) >> 21
 | |
| 	carry[0] = (s0 + (1048576)) >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[2] = (s2 + (1048576)) >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[4] = (s4 + (1048576)) >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[6] = (s6 + (1048576)) >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[8] = (s8 + (1048576)) >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[10] = (s10 + (1048576)) >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 	carry[12] = (s12 + (1048576)) >> 21
 | |
| 	s13 += carry[12]
 | |
| 	s12 -= carry[12] * 2097152
 | |
| 	carry[14] = (s14 + (1048576)) >> 21
 | |
| 	s15 += carry[14]
 | |
| 	s14 -= carry[14] * 2097152
 | |
| 	carry[16] = (s16 + (1048576)) >> 21
 | |
| 	s17 += carry[16]
 | |
| 	s16 -= carry[16] * 2097152
 | |
| 	carry[18] = (s18 + (1048576)) >> 21
 | |
| 	s19 += carry[18]
 | |
| 	s18 -= carry[18] * 2097152
 | |
| 	carry[20] = (s20 + (1048576)) >> 21
 | |
| 	s21 += carry[20]
 | |
| 	s20 -= carry[20] * 2097152
 | |
| 	carry[22] = (s22 + (1048576)) >> 21
 | |
| 	s23 += carry[22]
 | |
| 	s22 -= carry[22] * 2097152
 | |
| 
 | |
| 	carry[1] = (s1 + (1048576)) >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[3] = (s3 + (1048576)) >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[5] = (s5 + (1048576)) >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[7] = (s7 + (1048576)) >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[9] = (s9 + (1048576)) >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[11] = (s11 + (1048576)) >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 	carry[13] = (s13 + (1048576)) >> 21
 | |
| 	s14 += carry[13]
 | |
| 	s13 -= carry[13] * 2097152
 | |
| 	carry[15] = (s15 + (1048576)) >> 21
 | |
| 	s16 += carry[15]
 | |
| 	s15 -= carry[15] * 2097152
 | |
| 	carry[17] = (s17 + (1048576)) >> 21
 | |
| 	s18 += carry[17]
 | |
| 	s17 -= carry[17] * 2097152
 | |
| 	carry[19] = (s19 + (1048576)) >> 21
 | |
| 	s20 += carry[19]
 | |
| 	s19 -= carry[19] * 2097152
 | |
| 	carry[21] = (s21 + (1048576)) >> 21
 | |
| 	s22 += carry[21]
 | |
| 	s21 -= carry[21] * 2097152
 | |
| 
 | |
| 	s11 += s23 * 666643
 | |
| 	s12 += s23 * 470296
 | |
| 	s13 += s23 * 654183
 | |
| 	s14 -= s23 * 997805
 | |
| 	s15 += s23 * 136657
 | |
| 	s16 -= s23 * 683901
 | |
| 	s23 = 0
 | |
| 
 | |
| 	s10 += s22 * 666643
 | |
| 	s11 += s22 * 470296
 | |
| 	s12 += s22 * 654183
 | |
| 	s13 -= s22 * 997805
 | |
| 	s14 += s22 * 136657
 | |
| 	s15 -= s22 * 683901
 | |
| 	s22 = 0
 | |
| 
 | |
| 	s9 += s21 * 666643
 | |
| 	s10 += s21 * 470296
 | |
| 	s11 += s21 * 654183
 | |
| 	s12 -= s21 * 997805
 | |
| 	s13 += s21 * 136657
 | |
| 	s14 -= s21 * 683901
 | |
| 	s21 = 0
 | |
| 
 | |
| 	s8 += s20 * 666643
 | |
| 	s9 += s20 * 470296
 | |
| 	s10 += s20 * 654183
 | |
| 	s11 -= s20 * 997805
 | |
| 	s12 += s20 * 136657
 | |
| 	s13 -= s20 * 683901
 | |
| 	s20 = 0
 | |
| 
 | |
| 	s7 += s19 * 666643
 | |
| 	s8 += s19 * 470296
 | |
| 	s9 += s19 * 654183
 | |
| 	s10 -= s19 * 997805
 | |
| 	s11 += s19 * 136657
 | |
| 	s12 -= s19 * 683901
 | |
| 	s19 = 0
 | |
| 
 | |
| 	s6 += s18 * 666643
 | |
| 	s7 += s18 * 470296
 | |
| 	s8 += s18 * 654183
 | |
| 	s9 -= s18 * 997805
 | |
| 	s10 += s18 * 136657
 | |
| 	s11 -= s18 * 683901
 | |
| 	s18 = 0
 | |
| 
 | |
| 	carry[6] = (s6 + (1048576)) >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[8] = (s8 + (1048576)) >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[10] = (s10 + (1048576)) >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 	carry[12] = (s12 + (1048576)) >> 21
 | |
| 	s13 += carry[12]
 | |
| 	s12 -= carry[12] * 2097152
 | |
| 	carry[14] = (s14 + (1048576)) >> 21
 | |
| 	s15 += carry[14]
 | |
| 	s14 -= carry[14] * 2097152
 | |
| 	carry[16] = (s16 + (1048576)) >> 21
 | |
| 	s17 += carry[16]
 | |
| 	s16 -= carry[16] * 2097152
 | |
| 
 | |
| 	carry[7] = (s7 + (1048576)) >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[9] = (s9 + (1048576)) >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[11] = (s11 + (1048576)) >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 	carry[13] = (s13 + (1048576)) >> 21
 | |
| 	s14 += carry[13]
 | |
| 	s13 -= carry[13] * 2097152
 | |
| 	carry[15] = (s15 + (1048576)) >> 21
 | |
| 	s16 += carry[15]
 | |
| 	s15 -= carry[15] * 2097152
 | |
| 
 | |
| 	s5 += s17 * 666643
 | |
| 	s6 += s17 * 470296
 | |
| 	s7 += s17 * 654183
 | |
| 	s8 -= s17 * 997805
 | |
| 	s9 += s17 * 136657
 | |
| 	s10 -= s17 * 683901
 | |
| 	s17 = 0
 | |
| 
 | |
| 	s4 += s16 * 666643
 | |
| 	s5 += s16 * 470296
 | |
| 	s6 += s16 * 654183
 | |
| 	s7 -= s16 * 997805
 | |
| 	s8 += s16 * 136657
 | |
| 	s9 -= s16 * 683901
 | |
| 	s16 = 0
 | |
| 
 | |
| 	s3 += s15 * 666643
 | |
| 	s4 += s15 * 470296
 | |
| 	s5 += s15 * 654183
 | |
| 	s6 -= s15 * 997805
 | |
| 	s7 += s15 * 136657
 | |
| 	s8 -= s15 * 683901
 | |
| 	s15 = 0
 | |
| 
 | |
| 	s2 += s14 * 666643
 | |
| 	s3 += s14 * 470296
 | |
| 	s4 += s14 * 654183
 | |
| 	s5 -= s14 * 997805
 | |
| 	s6 += s14 * 136657
 | |
| 	s7 -= s14 * 683901
 | |
| 	s14 = 0
 | |
| 
 | |
| 	s1 += s13 * 666643
 | |
| 	s2 += s13 * 470296
 | |
| 	s3 += s13 * 654183
 | |
| 	s4 -= s13 * 997805
 | |
| 	s5 += s13 * 136657
 | |
| 	s6 -= s13 * 683901
 | |
| 	s13 = 0
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = (s0 + (1048576)) >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[2] = (s2 + (1048576)) >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[4] = (s4 + (1048576)) >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[6] = (s6 + (1048576)) >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[8] = (s8 + (1048576)) >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[10] = (s10 + (1048576)) >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 
 | |
| 	carry[1] = (s1 + (1048576)) >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[3] = (s3 + (1048576)) >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[5] = (s5 + (1048576)) >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[7] = (s7 + (1048576)) >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[9] = (s9 + (1048576)) >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[11] = (s11 + (1048576)) >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = s0 >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[1] = s1 >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[2] = s2 >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[3] = s3 >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[4] = s4 >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[5] = s5 >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[6] = s6 >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[7] = s7 >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[8] = s8 >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[9] = s9 >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[10] = s10 >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 	carry[11] = s11 >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = s0 >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[1] = s1 >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[2] = s2 >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[3] = s3 >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[4] = s4 >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[5] = s5 >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[6] = s6 >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[7] = s7 >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[8] = s8 >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[9] = s9 >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[10] = s10 >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 
 | |
| 	s[0] = byte(s0 >> 0)
 | |
| 	s[1] = byte(s0 >> 8)
 | |
| 	s[2] = byte((s0 >> 16) | (s1 * 32))
 | |
| 	s[3] = byte(s1 >> 3)
 | |
| 	s[4] = byte(s1 >> 11)
 | |
| 	s[5] = byte((s1 >> 19) | (s2 * 4))
 | |
| 	s[6] = byte(s2 >> 6)
 | |
| 	s[7] = byte((s2 >> 14) | (s3 * 128))
 | |
| 	s[8] = byte(s3 >> 1)
 | |
| 	s[9] = byte(s3 >> 9)
 | |
| 	s[10] = byte((s3 >> 17) | (s4 * 16))
 | |
| 	s[11] = byte(s4 >> 4)
 | |
| 	s[12] = byte(s4 >> 12)
 | |
| 	s[13] = byte((s4 >> 20) | (s5 * 2))
 | |
| 	s[14] = byte(s5 >> 7)
 | |
| 	s[15] = byte((s5 >> 15) | (s6 * 64))
 | |
| 	s[16] = byte(s6 >> 2)
 | |
| 	s[17] = byte(s6 >> 10)
 | |
| 	s[18] = byte((s6 >> 18) | (s7 * 8))
 | |
| 	s[19] = byte(s7 >> 5)
 | |
| 	s[20] = byte(s7 >> 13)
 | |
| 	s[21] = byte(s8 >> 0)
 | |
| 	s[22] = byte(s8 >> 8)
 | |
| 	s[23] = byte((s8 >> 16) | (s9 * 32))
 | |
| 	s[24] = byte(s9 >> 3)
 | |
| 	s[25] = byte(s9 >> 11)
 | |
| 	s[26] = byte((s9 >> 19) | (s10 * 4))
 | |
| 	s[27] = byte(s10 >> 6)
 | |
| 	s[28] = byte((s10 >> 14) | (s11 * 128))
 | |
| 	s[29] = byte(s11 >> 1)
 | |
| 	s[30] = byte(s11 >> 9)
 | |
| 	s[31] = byte(s11 >> 17)
 | |
| }
 | |
| 
 | |
| // Input:
 | |
| //   s[0]+256*s[1]+...+256^63*s[63] = s
 | |
| //
 | |
| // Output:
 | |
| //   s[0]+256*s[1]+...+256^31*s[31] = s mod l
 | |
| //   where l = 2^252 + 27742317777372353535851937790883648493.
 | |
| fn sc_reduce(mut out [32]byte, mut s []byte) {
 | |
| 	assert out.len == 32
 | |
| 	assert s.len == 64
 | |
| 	mut s0 := 2097151 & load3(s[..])
 | |
| 	mut s1 := 2097151 & (load4(s[2..]) >> 5)
 | |
| 	mut s2 := 2097151 & (load3(s[5..]) >> 2)
 | |
| 	mut s3 := 2097151 & (load4(s[7..]) >> 7)
 | |
| 	mut s4 := 2097151 & (load4(s[10..]) >> 4)
 | |
| 	mut s5 := 2097151 & (load3(s[13..]) >> 1)
 | |
| 	mut s6 := 2097151 & (load4(s[15..]) >> 6)
 | |
| 	mut s7 := 2097151 & (load3(s[18..]) >> 3)
 | |
| 	mut s8 := 2097151 & load3(s[21..])
 | |
| 	mut s9 := 2097151 & (load4(s[23..]) >> 5)
 | |
| 	mut s10 := 2097151 & (load3(s[26..]) >> 2)
 | |
| 	mut s11 := 2097151 & (load4(s[28..]) >> 7)
 | |
| 	mut s12 := 2097151 & (load4(s[31..]) >> 4)
 | |
| 	mut s13 := 2097151 & (load3(s[34..]) >> 1)
 | |
| 	mut s14 := 2097151 & (load4(s[36..]) >> 6)
 | |
| 	mut s15 := 2097151 & (load3(s[39..]) >> 3)
 | |
| 	mut s16 := 2097151 & load3(s[42..])
 | |
| 	mut s17 := 2097151 & (load4(s[44..]) >> 5)
 | |
| 	mut s18 := 2097151 & (load3(s[47..]) >> 2)
 | |
| 	mut s19 := 2097151 & (load4(s[49..]) >> 7)
 | |
| 	mut s20 := 2097151 & (load4(s[52..]) >> 4)
 | |
| 	mut s21 := 2097151 & (load3(s[55..]) >> 1)
 | |
| 	mut s22 := 2097151 & (load4(s[57..]) >> 6)
 | |
| 	mut s23 := (load4(s[60..]) >> 3)
 | |
| 
 | |
| 	s11 += s23 * 666643
 | |
| 	s12 += s23 * 470296
 | |
| 	s13 += s23 * 654183
 | |
| 	s14 -= s23 * 997805
 | |
| 	s15 += s23 * 136657
 | |
| 	s16 -= s23 * 683901
 | |
| 	s23 = 0
 | |
| 
 | |
| 	s10 += s22 * 666643
 | |
| 	s11 += s22 * 470296
 | |
| 	s12 += s22 * 654183
 | |
| 	s13 -= s22 * 997805
 | |
| 	s14 += s22 * 136657
 | |
| 	s15 -= s22 * 683901
 | |
| 	s22 = 0
 | |
| 
 | |
| 	s9 += s21 * 666643
 | |
| 	s10 += s21 * 470296
 | |
| 	s11 += s21 * 654183
 | |
| 	s12 -= s21 * 997805
 | |
| 	s13 += s21 * 136657
 | |
| 	s14 -= s21 * 683901
 | |
| 	s21 = 0
 | |
| 
 | |
| 	s8 += s20 * 666643
 | |
| 	s9 += s20 * 470296
 | |
| 	s10 += s20 * 654183
 | |
| 	s11 -= s20 * 997805
 | |
| 	s12 += s20 * 136657
 | |
| 	s13 -= s20 * 683901
 | |
| 	s20 = 0
 | |
| 
 | |
| 	s7 += s19 * 666643
 | |
| 	s8 += s19 * 470296
 | |
| 	s9 += s19 * 654183
 | |
| 	s10 -= s19 * 997805
 | |
| 	s11 += s19 * 136657
 | |
| 	s12 -= s19 * 683901
 | |
| 	s19 = 0
 | |
| 
 | |
| 	s6 += s18 * 666643
 | |
| 	s7 += s18 * 470296
 | |
| 	s8 += s18 * 654183
 | |
| 	s9 -= s18 * 997805
 | |
| 	s10 += s18 * 136657
 | |
| 	s11 -= s18 * 683901
 | |
| 	s18 = 0
 | |
| 
 | |
| 	mut carry := [17]i64{} // original one
 | |
| 	// mut carry := [17]u64{}
 | |
| 
 | |
| 	carry[6] = (s6 + (1048576)) >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[8] = (s8 + (1048576)) >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[10] = (s10 + (1048576)) >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 	carry[12] = (s12 + (1048576)) >> 21
 | |
| 	s13 += carry[12]
 | |
| 	s12 -= carry[12] * 2097152
 | |
| 	carry[14] = (s14 + (1048576)) >> 21
 | |
| 	s15 += carry[14]
 | |
| 	s14 -= carry[14] * 2097152
 | |
| 	carry[16] = (s16 + (1048576)) >> 21
 | |
| 	s17 += carry[16]
 | |
| 	s16 -= carry[16] * 2097152
 | |
| 
 | |
| 	carry[7] = (s7 + (1048576)) >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[9] = (s9 + (1048576)) >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[11] = (s11 + (1048576)) >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 	carry[13] = (s13 + (1048576)) >> 21
 | |
| 	s14 += carry[13]
 | |
| 	s13 -= carry[13] * 2097152
 | |
| 	carry[15] = (s15 + (1048576)) >> 21
 | |
| 	s16 += carry[15]
 | |
| 	s15 -= carry[15] * 2097152
 | |
| 
 | |
| 	s5 += s17 * 666643
 | |
| 	s6 += s17 * 470296
 | |
| 	s7 += s17 * 654183
 | |
| 	s8 -= s17 * 997805
 | |
| 	s9 += s17 * 136657
 | |
| 	s10 -= s17 * 683901
 | |
| 	s17 = 0
 | |
| 
 | |
| 	s4 += s16 * 666643
 | |
| 	s5 += s16 * 470296
 | |
| 	s6 += s16 * 654183
 | |
| 	s7 -= s16 * 997805
 | |
| 	s8 += s16 * 136657
 | |
| 	s9 -= s16 * 683901
 | |
| 	s16 = 0
 | |
| 
 | |
| 	s3 += s15 * 666643
 | |
| 	s4 += s15 * 470296
 | |
| 	s5 += s15 * 654183
 | |
| 	s6 -= s15 * 997805
 | |
| 	s7 += s15 * 136657
 | |
| 	s8 -= s15 * 683901
 | |
| 	s15 = 0
 | |
| 
 | |
| 	s2 += s14 * 666643
 | |
| 	s3 += s14 * 470296
 | |
| 	s4 += s14 * 654183
 | |
| 	s5 -= s14 * 997805
 | |
| 	s6 += s14 * 136657
 | |
| 	s7 -= s14 * 683901
 | |
| 	s14 = 0
 | |
| 
 | |
| 	s1 += s13 * 666643
 | |
| 	s2 += s13 * 470296
 | |
| 	s3 += s13 * 654183
 | |
| 	s4 -= s13 * 997805
 | |
| 	s5 += s13 * 136657
 | |
| 	s6 -= s13 * 683901
 | |
| 	s13 = 0
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = (s0 + (1048576)) >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[2] = (s2 + (1048576)) >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[4] = (s4 + (1048576)) >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[6] = (s6 + (1048576)) >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[8] = (s8 + (1048576)) >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[10] = (s10 + (1048576)) >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 
 | |
| 	carry[1] = (s1 + (1048576)) >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[3] = (s3 + (1048576)) >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[5] = (s5 + (1048576)) >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[7] = (s7 + (1048576)) >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[9] = (s9 + (1048576)) >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[11] = (s11 + (1048576)) >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = s0 >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[1] = s1 >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[2] = s2 >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[3] = s3 >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[4] = s4 >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[5] = s5 >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[6] = s6 >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[7] = s7 >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[8] = s8 >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[9] = s9 >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[10] = s10 >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 	carry[11] = s11 >> 21
 | |
| 	s12 += carry[11]
 | |
| 	s11 -= carry[11] * 2097152
 | |
| 
 | |
| 	s0 += s12 * 666643
 | |
| 	s1 += s12 * 470296
 | |
| 	s2 += s12 * 654183
 | |
| 	s3 -= s12 * 997805
 | |
| 	s4 += s12 * 136657
 | |
| 	s5 -= s12 * 683901
 | |
| 	s12 = 0
 | |
| 
 | |
| 	carry[0] = s0 >> 21
 | |
| 	s1 += carry[0]
 | |
| 	s0 -= carry[0] * 2097152
 | |
| 	carry[1] = s1 >> 21
 | |
| 	s2 += carry[1]
 | |
| 	s1 -= carry[1] * 2097152
 | |
| 	carry[2] = s2 >> 21
 | |
| 	s3 += carry[2]
 | |
| 	s2 -= carry[2] * 2097152
 | |
| 	carry[3] = s3 >> 21
 | |
| 	s4 += carry[3]
 | |
| 	s3 -= carry[3] * 2097152
 | |
| 	carry[4] = s4 >> 21
 | |
| 	s5 += carry[4]
 | |
| 	s4 -= carry[4] * 2097152
 | |
| 	carry[5] = s5 >> 21
 | |
| 	s6 += carry[5]
 | |
| 	s5 -= carry[5] * 2097152
 | |
| 	carry[6] = s6 >> 21
 | |
| 	s7 += carry[6]
 | |
| 	s6 -= carry[6] * 2097152
 | |
| 	carry[7] = s7 >> 21
 | |
| 	s8 += carry[7]
 | |
| 	s7 -= carry[7] * 2097152
 | |
| 	carry[8] = s8 >> 21
 | |
| 	s9 += carry[8]
 | |
| 	s8 -= carry[8] * 2097152
 | |
| 	carry[9] = s9 >> 21
 | |
| 	s10 += carry[9]
 | |
| 	s9 -= carry[9] * 2097152
 | |
| 	carry[10] = s10 >> 21
 | |
| 	s11 += carry[10]
 | |
| 	s10 -= carry[10] * 2097152
 | |
| 
 | |
| 	out[0] = byte(s0 >> 0)
 | |
| 	out[1] = byte(s0 >> 8)
 | |
| 	out[2] = byte((s0 >> 16) | (s1 * 32))
 | |
| 	out[3] = byte(s1 >> 3)
 | |
| 	out[4] = byte(s1 >> 11)
 | |
| 	out[5] = byte((s1 >> 19) | (s2 * 4))
 | |
| 	out[6] = byte(s2 >> 6)
 | |
| 	out[7] = byte((s2 >> 14) | (s3 * 128))
 | |
| 	out[8] = byte(s3 >> 1)
 | |
| 	out[9] = byte(s3 >> 9)
 | |
| 	out[10] = byte((s3 >> 17) | (s4 * 16))
 | |
| 	out[11] = byte(s4 >> 4)
 | |
| 	out[12] = byte(s4 >> 12)
 | |
| 	out[13] = byte((s4 >> 20) | (s5 * 2))
 | |
| 	out[14] = byte(s5 >> 7)
 | |
| 	out[15] = byte((s5 >> 15) | (s6 * 64))
 | |
| 	out[16] = byte(s6 >> 2)
 | |
| 	out[17] = byte(s6 >> 10)
 | |
| 	out[18] = byte((s6 >> 18) | (s7 * 8))
 | |
| 	out[19] = byte(s7 >> 5)
 | |
| 	out[20] = byte(s7 >> 13)
 | |
| 	out[21] = byte(s8 >> 0)
 | |
| 	out[22] = byte(s8 >> 8)
 | |
| 	out[23] = byte((s8 >> 16) | (s9 * 32))
 | |
| 	out[24] = byte(s9 >> 3)
 | |
| 	out[25] = byte(s9 >> 11)
 | |
| 	out[26] = byte((s9 >> 19) | (s10 * 4))
 | |
| 	out[27] = byte(s10 >> 6)
 | |
| 	out[28] = byte((s10 >> 14) | (s11 * 128))
 | |
| 	out[29] = byte(s11 >> 1)
 | |
| 	out[30] = byte(s11 >> 9)
 | |
| 	out[31] = byte(s11 >> 17)
 | |
| }
 | |
| 
 | |
| // non_adjacent_form computes a width-w non-adjacent form for this scalar.
 | |
| //
 | |
| // w must be between 2 and 8, or non_adjacent_form will panic.
 | |
| pub fn (mut s Scalar) non_adjacent_form(w u32) []i8 {
 | |
| 	// This implementation is adapted from the one
 | |
| 	// in curve25519-dalek and is documented there:
 | |
| 	// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
 | |
| 	if s.s[31] > 127 {
 | |
| 		panic('scalar has high bit set illegally')
 | |
| 	}
 | |
| 	if w < 2 {
 | |
| 		panic('w must be at least 2 by the definition of NAF')
 | |
| 	} else if w > 8 {
 | |
| 		panic('NAF digits must fit in i8')
 | |
| 	}
 | |
| 
 | |
| 	mut naf := []i8{len: 256}
 | |
| 	mut digits := [5]u64{}
 | |
| 
 | |
| 	for i := 0; i < 4; i++ {
 | |
| 		digits[i] = binary.little_endian_u64(s.s[i * 8..])
 | |
| 	}
 | |
| 
 | |
| 	width := u64(1 << w)
 | |
| 	window_mask := u64(width - 1)
 | |
| 
 | |
| 	mut pos := u32(0)
 | |
| 	mut carry := u64(0)
 | |
| 	for pos < 256 {
 | |
| 		idx_64 := pos / 64
 | |
| 		idx_bit := pos % 64
 | |
| 		mut bitbuf := u64(0)
 | |
| 		if idx_bit < 64 - w {
 | |
| 			// This window's bits are contained in a single u64
 | |
| 			bitbuf = digits[idx_64] >> idx_bit
 | |
| 		} else {
 | |
| 			// Combine the current 64 bits with bits from the next 64
 | |
| 			bitbuf = (digits[idx_64] >> idx_bit) | (digits[1 + idx_64] << (64 - idx_bit))
 | |
| 		}
 | |
| 
 | |
| 		// Add carry into the current window
 | |
| 		window := carry + (bitbuf & window_mask)
 | |
| 
 | |
| 		if window & 1 == 0 {
 | |
| 			// If the window value is even, preserve the carry and continue.
 | |
| 			// Why is the carry preserved?
 | |
| 			// If carry == 0 and window & 1 == 0,
 | |
| 			//    then the next carry should be 0
 | |
| 			// If carry == 1 and window & 1 == 0,
 | |
| 			//    then bit_buf & 1 == 1 so the next carry should be 1
 | |
| 			pos += 1
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if window < width / 2 {
 | |
| 			carry = 0
 | |
| 			naf[pos] = i8(window)
 | |
| 		} else {
 | |
| 			carry = 1
 | |
| 			naf[pos] = i8(window) - i8(width)
 | |
| 		}
 | |
| 
 | |
| 		pos += w
 | |
| 	}
 | |
| 	return naf
 | |
| }
 | |
| 
 | |
| fn (mut s Scalar) signed_radix16() []i8 {
 | |
| 	if s.s[31] > 127 {
 | |
| 		panic('scalar has high bit set illegally')
 | |
| 	}
 | |
| 
 | |
| 	mut digits := []i8{len: 64}
 | |
| 
 | |
| 	// Compute unsigned radix-16 digits:
 | |
| 	for i := 0; i < 32; i++ {
 | |
| 		digits[2 * i] = i8(s.s[i] & 15)
 | |
| 		digits[2 * i + 1] = i8((s.s[i] >> 4) & 15)
 | |
| 	}
 | |
| 
 | |
| 	// Recenter coefficients:
 | |
| 	for i := 0; i < 63; i++ {
 | |
| 		mut carry := (digits[i] + 8) >> 4
 | |
| 
 | |
| 		// digits[i] -= unsafe { carry * 16 } // original one
 | |
| 		digits[i] -= unsafe { carry * 16 } // carry * 16 == carry *
 | |
| 
 | |
| 		digits[i + 1] += carry
 | |
| 	}
 | |
| 
 | |
| 	return digits
 | |
| }
 | |
| 
 | |
| // utility function
 | |
| // generate returns a valid (reduced modulo l) Scalar with a distribution
 | |
| // weighted towards high, low, and edge values.
 | |
| fn generate_scalar(size int) ?Scalar {
 | |
| 	/*
 | |
| 	s := scZero
 | |
| 	diceRoll := rand.Intn(100)
 | |
| 	switch {
 | |
| 	case diceRoll == 0:
 | |
| 	case diceRoll == 1:
 | |
| 		s = scOne
 | |
| 	case diceRoll == 2:
 | |
| 		s = scMinusOne
 | |
| 	case diceRoll < 5:
 | |
| 		// Generate a low scalar in [0, 2^125).
 | |
| 		rand.Read(s.s[:16])
 | |
| 		s.s[15] &= (1 * 32) - 1
 | |
| 	case diceRoll < 10:
 | |
| 		// Generate a high scalar in [2^252, 2^252 + 2^124).
 | |
| 		s.s[31] = 1 * 16
 | |
| 		rand.Read(s.s[:16])
 | |
| 		s.s[15] &= (1 * 16) - 1
 | |
| 	default:
 | |
| 		// Generate a valid scalar in [0, l) by returning [0, 2^252) which has a
 | |
| 		// negligibly different distribution (the former has a 2^-127.6 chance
 | |
| 		// of being out of the latter range).
 | |
| 		rand.Read(s.s[:])
 | |
| 		s.s[31] &= (1 * 16) - 1
 | |
| 	}
 | |
| 	return reflect.ValueOf(s)
 | |
| 	*/
 | |
| 	mut s := edwards25519.sc_zero
 | |
| 	diceroll := rand.intn(100) or { 0 }
 | |
| 	match true {
 | |
| 		/*
 | |
| 		case diceroll == 0:
 | |
| 			case diceroll == 1:
 | |
| 		*/
 | |
| 		diceroll == 0 || diceroll == 1 {
 | |
| 			s = edwards25519.sc_one
 | |
| 		}
 | |
| 		diceroll == 2 {
 | |
| 			s = edwards25519.sc_minus_one
 | |
| 		}
 | |
| 		diceroll < 5 {
 | |
| 			// rand.Read(s.s[:16]) // read random bytes and fill buf
 | |
| 			// using builtin rand.read([]buf)
 | |
| 			rand.read(mut s.s[..16])
 | |
| 			// buf := rand.read(s.s[..16].len) ?
 | |
| 			// copy(mut s.s[..16], buf)
 | |
| 
 | |
| 			/*
 | |
| 			for i, item in buf {
 | |
| 				s.s[i] = item
 | |
| 			}
 | |
| 			*/
 | |
| 			s.s[15] &= (1 * 32) - 1
 | |
| 			// generate a low scalar in [0, 2^125).
 | |
| 		}
 | |
| 		diceroll < 10 {
 | |
| 			// generate a high scalar in [2^252, 2^252 + 2^124).
 | |
| 			s.s[31] = 1 * 16
 | |
| 			// Read generates len(p) random bytes and writes them into p
 | |
| 			// rand.Read(s.s[:16])
 | |
| 			rand.read(mut s.s[..16])
 | |
| 			// buf := rand.read(s.s[..16].len) ?
 | |
| 			// copy(mut s.s[..16], buf)
 | |
| 
 | |
| 			/*
 | |
| 			for i, item in buf {
 | |
| 				s.s[i] = item
 | |
| 			}
 | |
| 			*/
 | |
| 			s.s[15] &= (1 * 16) - 1
 | |
| 		}
 | |
| 		else {
 | |
| 			// generate a valid scalar in [0, l) by returning [0, 2^252) which has a
 | |
| 			// negligibly different distribution (the former has a 2^-127.6 chance
 | |
| 			// of being out of the latter range).
 | |
| 			// rand.Read(s.s[:])
 | |
| 			rand.read(mut s.s[..])
 | |
| 			// buf := crand.read(s.s.len) ?
 | |
| 			// copy(mut s.s[..], buf)
 | |
| 
 | |
| 			/*
 | |
| 			for i, item in buf {
 | |
| 				s.s[i] = item
 | |
| 			}
 | |
| 			*/
 | |
| 			s.s[31] &= (1 * 16) - 1
 | |
| 		}
 | |
| 	}
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| type NotZeroScalar = Scalar
 | |
| 
 | |
| fn generate_notzero_scalar(size int) ?NotZeroScalar {
 | |
| 	mut s := Scalar{}
 | |
| 	for s == edwards25519.sc_zero {
 | |
| 		s = generate_scalar(size) ?
 | |
| 	}
 | |
| 	return NotZeroScalar(s)
 | |
| }
 |