v

Зеркало из https://github.com/vlang/v
Форк
0
202 строки · 5.2 Кб
1
module edwards25519
2

3
import os
4
import rand
5
import encoding.hex
6

7
const github_job = os.getenv('GITHUB_JOB')
8

9
fn testsuite_begin() {
10
	if github_job != '' {
11
		// ensure that the CI does not run flaky tests:
12
		rand.seed([u32(0xffff24), 0xabcd])
13
	}
14
}
15

16
// test_bytes_montgomery tests the set_bytes_with_clamping+bytes_montgomery path
17
// equivalence to curve25519.X25519 for basepoint scalar multiplications.
18
//
19
// Note that you can't actually implement X25519 with this package because
20
// there is no SetBytesMontgomery, and it would not be possible to implement
21
// it properly: points on the twist would get rejected, and the Scalar returned
22
// by set_bytes_with_clamping does not preserve its cofactor-clearing properties.
23
//
24
// Disabled curve25519 not available yet, but maybe can use own curve25519
25
/*
26
fn fn_mon(scalar [32]u8) bool {
27
               mut s := new_scalar().set_bytes_with_clamping(scalar[..])
28
               p := (&Point{}).scalar_base_mult(s)
29
               got := p.bytes_montgomery()
30
               want, _ := curve25519.X25519(scalar[..], curve25519.Basepoint)
31
               return bytes.equal(got, want)
32
       }
33

34
fn test_bytes_montgomery() {
35
       /* f := fn(scalar [32]u8) bool {
36
               s := new_scalar().set_bytes_with_clamping(scalar[..])
37
               p := (&Point{}).scalar_base_mult(s)
38
               got := p.bytes_montgomery()
39
               want, _ := curve25519.X25519(scalar[..], curve25519.Basepoint)
40
               return bytes.equal(got, want)
41
       } */
42
       if err := quick.Check(f, nil); err != nil {
43
               t.Error(err)
44
       }
45
}*/
46

47
fn test_bytes_montgomery_sodium() {
48
	// Generated with libsodium.js 1.0.18
49
	// crypto_sign_keypair().pubkey
50
	pubkey := '3bf918ffc2c955dc895bf145f566fb96623c1cadbe040091175764b5fde322c0'
51
	mut p := Point{}
52
	p.set_bytes(hex.decode(pubkey)!)!
53

54
	// crypto_sign_ed25519_pk_to_curve25519(pubkey)
55
	want := 'efc6c9d0738e9ea18d738ad4a2653631558931b0f1fde4dd58c436d19686dc28'
56
	got := hex.encode(p.bytes_montgomery())
57
	assert got == want
58
}
59

60
fn test_bytes_montgomery_infinity() {
61
	mut p := new_identity_point()
62
	want := '0000000000000000000000000000000000000000000000000000000000000000'
63
	got := hex.encode(p.bytes_montgomery())
64

65
	assert got == want
66
}
67

68
const loworder_string = '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85'
69
const loworder_bytes = hex.decode(loworder_string) or { panic(err) }
70

71
fn fn_cofactor(mut data []u8) bool {
72
	if data.len != 64 {
73
		panic('data.len should be 64')
74
	}
75
	mut loworder := Point{}
76
	loworder.set_bytes(loworder_bytes) or { panic(err) }
77

78
	mut s := new_scalar()
79
	mut p := Point{}
80
	mut p8 := Point{}
81
	s.set_uniform_bytes(data) or { panic(err) }
82
	p.scalar_base_mult(mut s)
83
	p8.mult_by_cofactor(p)
84

85
	assert check_on_curve(p8) == true
86

87
	// 8 * p == (8 * s) * B
88
	mut sc := Scalar{
89
		s: [32]u8{}
90
	}
91
	sc.s[0] = u8(0x08)
92
	s.multiply(s, sc)
93
	mut pp := Point{}
94
	pp.scalar_base_mult(mut s)
95
	if p8.equal(pp) != 1 {
96
		return false
97
	}
98

99
	// 8 * p == 8 * (loworder + p)
100
	pp.add(p, loworder)
101
	pp.mult_by_cofactor(pp)
102
	if p8.equal(pp) != 1 {
103
		return false
104
	}
105

106
	// 8 * p == p + p + p + p + p + p + p + p
107
	pp.set(new_identity_point())
108
	for i := 0; i < 8; i++ {
109
		pp.add(pp, p)
110
	}
111
	return p8.equal(pp) == 1
112
}
113

114
fn test_mult_by_cofactor() {
115
	mut loworder := Point{}
116
	mut data := rand.bytes(64)!
117

118
	assert fn_cofactor(mut data) == true
119
}
120

121
fn invert_works(mut xinv Scalar, x NotZeroScalar) bool {
122
	xinv.invert(x)
123
	mut check := Scalar{}
124
	check.multiply(x, xinv)
125
	return check == sc_one && is_reduced(xinv)
126
}
127

128
fn test_scalar_invert() {
129
	nsc := generate_notzero_scalar(5) or { panic(err) }
130
	mut xsc := generate_scalar(5) or { panic(err) }
131
	assert invert_works(mut xsc, nsc) == true
132

133
	mut zero := new_scalar()
134
	mut xx := new_scalar()
135
	xx.invert(zero)
136
	assert xx.equal(zero) == 1
137
}
138

139
fn test_multiscalarmultmatchesbasemult() {
140
	for i in 0 .. 6 {
141
		x := generate_scalar(100) or { panic(err) }
142
		y := generate_scalar(5) or { panic(err) }
143
		z := generate_scalar(2) or { panic(err) }
144
		assert multiscalarmultmatchesbasemult(x, y, z) == true
145
	}
146
}
147

148
fn multiscalarmultmatchesbasemult(xx Scalar, yy Scalar, zz Scalar) bool {
149
	mut x := xx
150
	mut y := yy
151
	mut z := zz
152

153
	mut p := Point{}
154
	mut q1 := Point{}
155
	mut q2 := Point{}
156
	mut q3 := Point{}
157
	mut check := Point{}
158
	mut b := new_generator_point()
159

160
	p.multi_scalar_mult([x, y, z], [b, b, b])
161

162
	q1.scalar_base_mult(mut x)
163
	q2.scalar_base_mult(mut y)
164
	q3.scalar_base_mult(mut z)
165
	check.add(q1, q2)
166
	check.add(check, q3)
167

168
	check_on_curve(p, check, q1, q2, q3)
169
	return p.equal(check) == 1
170
}
171

172
fn vartime_multiscala_rmultmatches_basemult(xx Scalar, yy Scalar, zz Scalar) bool {
173
	mut x := xx
174
	mut y := yy
175
	mut z := zz
176
	mut p := Point{}
177
	mut q1 := Point{}
178
	mut q2 := Point{}
179
	mut q3 := Point{}
180
	mut check := Point{}
181
	mut b := new_generator_point()
182

183
	p.vartime_multiscalar_mult([x, y, z], [b, b, b])
184

185
	q1.scalar_base_mult(mut x)
186
	q2.scalar_base_mult(mut y)
187
	q3.scalar_base_mult(mut z)
188
	check.add(q1, q2)
189
	check.add(check, q3)
190

191
	check_on_curve(p, check, q1, q2, q3)
192
	return p.equal(check) == 1
193
}
194

195
fn test_vartimemultiscalarmultmatchesbasemult() {
196
	for i in 0 .. 5 {
197
		x := generate_scalar(100) or { panic(err) }
198
		y := generate_scalar(5) or { panic(err) }
199
		z := generate_scalar(2) or { panic(err) }
200
		assert vartime_multiscala_rmultmatches_basemult(x, y, z) == true
201
	}
202
}
203

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.