-
Notifications
You must be signed in to change notification settings - Fork 22.1k
Expand file tree
/
Copy pathalias_test.go
More file actions
131 lines (118 loc) · 4.18 KB
/
Copy pathalias_test.go
File metadata and controls
131 lines (118 loc) · 4.18 KB
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
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bn256
import (
"bytes"
"crypto/rand"
"math/big"
"testing"
)
// TestG1AddAliasing checks that G1.Add tolerates a receiver that aliases one of
// its operands. The case that used to break is a+b with a and b the same point:
// Add dispatches to curvePoint.Double, which computed z3 = 2*y1*z1 after it had
// already overwritten c.y, so an aliased receiver fed it the wrong y1.
func TestG1AddAliasing(t *testing.T) {
a := new(G1).ScalarBaseMult(big.NewInt(7))
b := new(G1).ScalarBaseMult(big.NewInt(11))
doubled := new(G1).ScalarMult(a, big.NewInt(2)).Marshal()
sum := new(G1).Add(a, b).Marshal()
got := new(G1).ScalarBaseMult(big.NewInt(7))
if got.Add(got, got); !bytes.Equal(got.Marshal(), doubled) {
t.Errorf("got.Add(got, got) = %x, want %x", got.Marshal(), doubled)
}
if got = new(G1).Add(a, a); !bytes.Equal(got.Marshal(), doubled) {
t.Errorf("new(G1).Add(a, a) = %x, want %x", got.Marshal(), doubled)
}
got = new(G1).ScalarBaseMult(big.NewInt(7))
if got.Add(got, b); !bytes.Equal(got.Marshal(), sum) {
t.Errorf("got.Add(got, b) = %x, want %x", got.Marshal(), sum)
}
got = new(G1).ScalarBaseMult(big.NewInt(11))
if got.Add(a, got); !bytes.Equal(got.Marshal(), sum) {
t.Errorf("got.Add(a, got) = %x, want %x", got.Marshal(), sum)
}
}
// TestG2AddAliasing is TestG1AddAliasing for the twist.
func TestG2AddAliasing(t *testing.T) {
a := new(G2).ScalarBaseMult(big.NewInt(7))
b := new(G2).ScalarBaseMult(big.NewInt(11))
doubled := new(G2).ScalarMult(a, big.NewInt(2)).Marshal()
sum := new(G2).Add(a, b).Marshal()
got := new(G2).ScalarBaseMult(big.NewInt(7))
if got.Add(got, got); !bytes.Equal(got.Marshal(), doubled) {
t.Errorf("got.Add(got, got) = %x, want %x", got.Marshal(), doubled)
}
if got = new(G2).Add(a, a); !bytes.Equal(got.Marshal(), doubled) {
t.Errorf("new(G2).Add(a, a) = %x, want %x", got.Marshal(), doubled)
}
got = new(G2).ScalarBaseMult(big.NewInt(7))
if got.Add(got, b); !bytes.Equal(got.Marshal(), sum) {
t.Errorf("got.Add(got, b) = %x, want %x", got.Marshal(), sum)
}
got = new(G2).ScalarBaseMult(big.NewInt(11))
if got.Add(a, got); !bytes.Equal(got.Marshal(), sum) {
t.Errorf("got.Add(a, got) = %x, want %x", got.Marshal(), sum)
}
}
// TestPointDoubleAliasing exercises the underlying Double and Negative directly,
// on random points, with and without an aliased receiver.
func TestPointDoubleAliasing(t *testing.T) {
pool := new(bnPool)
for i := 0; i < 10; i++ {
k, err := rand.Int(rand.Reader, Order)
if err != nil {
t.Fatal(err)
}
cp := newCurvePoint(pool).Mul(curveGen, k, pool)
want := newCurvePoint(pool)
want.Double(cp, pool)
want.MakeAffine(pool)
got := newCurvePoint(pool)
got.Set(cp)
got.Double(got, pool)
got.MakeAffine(pool)
if got.x.Cmp(want.x) != 0 || got.y.Cmp(want.y) != 0 {
t.Fatalf("%d: aliased curvePoint.Double = (%s, %s), want (%s, %s)", i, got.x, got.y, want.x, want.y)
}
want.Negative(cp)
want.MakeAffine(pool)
got.Set(cp)
got.Negative(got)
got.MakeAffine(pool)
if got.x.Cmp(want.x) != 0 || got.y.Cmp(want.y) != 0 {
t.Fatalf("%d: aliased curvePoint.Negative = (%s, %s), want (%s, %s)", i, got.x, got.y, want.x, want.y)
}
tp := newTwistPoint(pool).Mul(twistGen, k, pool)
wantT := newTwistPoint(pool)
wantT.Double(tp, pool)
wantT.MakeAffine(pool)
gotT := newTwistPoint(pool)
gotT.Set(tp)
gotT.Double(gotT, pool)
gotT.MakeAffine(pool)
if !twistEqual(gotT, wantT) {
t.Fatalf("%d: aliased twistPoint.Double disagrees with the unaliased result", i)
}
wantT.Negative(tp, pool)
wantT.MakeAffine(pool)
gotT.Set(tp)
gotT.Negative(gotT, pool)
gotT.MakeAffine(pool)
if !twistEqual(gotT, wantT) {
t.Fatalf("%d: aliased twistPoint.Negative disagrees with the unaliased result", i)
}
}
}
// twistEqual compares two affine twist points.
func twistEqual(a, b *twistPoint) bool {
if a.IsInfinity() || b.IsInfinity() {
return a.IsInfinity() == b.IsInfinity()
}
a.x.Minimal()
a.y.Minimal()
b.x.Minimal()
b.y.Minimal()
return a.x.x.Cmp(b.x.x) == 0 && a.x.y.Cmp(b.x.y) == 0 &&
a.y.x.Cmp(b.y.x) == 0 && a.y.y.Cmp(b.y.y) == 0
}