-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6bd7d00
Showing
33 changed files
with
323,466 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
notes.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module github.com/decentralisedkev/go-jubjub | ||
|
||
require ( | ||
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 // indirect | ||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect | ||
github.com/stretchr/testify v1.3.0 | ||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect | ||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc | ||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e // indirect | ||
) | ||
|
||
go 1.13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 h1:beB+Da4k9B1zmgag78k3k1Bx4L/fdWr5FwNa0f8RxmY= | ||
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= | ||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU= | ||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= | ||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M= | ||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI= | ||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package fq | ||
|
||
import "github.com/decentralisedkev/go-jubjub/internal/field" | ||
|
||
// q | ||
var q = Fq{0xffffffff00000001, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48} | ||
|
||
// q | ||
var qMod = field.Field{0xffffffff00000001, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48} | ||
|
||
var zeroF = field.Field{0, 0, 0, 0} | ||
|
||
var zero = Fq{0, 0, 0, 0} | ||
|
||
// INV = -(q^{-1} mod 2^64) mod 2^64 | ||
const INV uint64 = 0xfffffffeffffffff | ||
|
||
const S uint32 = 32 | ||
|
||
// R = 2^256 mod q | ||
var R = Fq{0x00000001fffffffe, 0x5884b7fa00034802, 0x998c4fefecbc4ff5, 0x1824b159acc5056f} | ||
|
||
// R2 = 2^512 mod q | ||
var R2 = Fq{0xc999e990f3f29c6d, 0x2b6cedcb87925c23, 0x05d314967254398f, 0x0748d9d99f59ff11} | ||
|
||
var r2 = field.Field{0xc999e990f3f29c6d, 0x2b6cedcb87925c23, 0x05d314967254398f, 0x0748d9d99f59ff11} | ||
|
||
// R3 = R2 * 2^256 mod q = 2^768 mod q | ||
var R3 = Fq{0xc62c1807439b73af, 0x1b3e0d188cf06990, 0x73d13c71c7b5f418, 0x6e2a5bb9c8db33e9} | ||
|
||
// R3 = R2 * 2^256 mod q = 2^768 mod q | ||
var r3 = field.Field{0xc62c1807439b73af, 0x1b3e0d188cf06990, 0x73d13c71c7b5f418, 0x6e2a5bb9c8db33e9} | ||
|
||
// ROOTOFUNITY GENERATOR^t where t * 2^s + 1 = q with t odd. | ||
var ROOTOFUNITY = Fq{0xb9b58d8c5f0e466a, 0x5b1b4c801819d7ec, 0x0af53ae352a31e64, 0x5bf3adda19e9b27b} | ||
|
||
// ~fq | ||
|
||
// D = -(10240/10241) | ||
var D = Fq{0x2a522455b974f6b0, 0xfc6cc9ef0d9acab3, 0x7a08fb94c27628d1, 0x57f8f6a8fe0e262e} | ||
|
||
// D2 = 2 * d | ||
var D2 = Fq{0x54a448ac72e9ed5f, 0xa51befdb1b373967, 0xc0d81f217b4a799e, 0x3c0445fed27ecf14} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,314 @@ | ||
package fq | ||
|
||
import ( | ||
"crypto/rand" | ||
"encoding/hex" | ||
"errors" | ||
|
||
"github.com/decentralisedkev/go-jubjub/internal/field" | ||
) | ||
|
||
type FieldQ struct { | ||
field.Field | ||
} | ||
|
||
// // INV = -(q^{-1} mod 2^64) mod 2^64 | ||
// const INV uint64 = 0xfffffffeffffffff | ||
|
||
var ( | ||
|
||
// R = 2^256 mod q | ||
montR = field.Field{0x00000001fffffffe, 0x5884b7fa00034802, 0x998c4fefecbc4ff5, 0x1824b159acc5056f} | ||
|
||
// R2 = 2^512 mod q | ||
montR2 = field.Field{0xc999e990f3f29c6d, 0x2b6cedcb87925c23, 0x05d314967254398f, 0x0748d9d99f59ff11} | ||
|
||
// R3 = R2 * 2^256 mod q = 2^768 mod q | ||
montR3 = field.Field{0xc62c1807439b73af, 0x1b3e0d188cf06990, 0x73d13c71c7b5f418, 0x6e2a5bb9c8db33e9} | ||
|
||
// ROOTOFUNITY GENERATOR^t where t * 2^s + 1 = q with t odd. | ||
rootOfUnity = field.Field{0xb9b58d8c5f0e466a, 0x5b1b4c801819d7ec, 0x0af53ae352a31e64, 0x5bf3adda19e9b27b} | ||
|
||
// D = -(10240/10241) | ||
d = field.Field{0x2a522455b974f6b0, 0xfc6cc9ef0d9acab3, 0x7a08fb94c27628d1, 0x57f8f6a8fe0e262e} | ||
|
||
// D2 = 2 * d | ||
d2 = field.Field{0x54a448ac72e9ed5f, 0xa51befdb1b373967, 0xc0d81f217b4a799e, 0x3c0445fed27ecf14} | ||
) | ||
|
||
func (f *FieldQ) IntoBytes() []byte { | ||
return f.Field.IntoBytes(INV, qMod) | ||
} | ||
|
||
func (f *FieldQ) BytesInto(buf *[32]byte) { | ||
f.Field.BytesInto(buf, qMod, INV) | ||
} | ||
|
||
func (f *FieldQ) Set(a FieldQ) *FieldQ { | ||
f.Field.Set(a.Field) | ||
return f | ||
} | ||
func (f *FieldQ) SetOne() *FieldQ { | ||
f.Field.Set(montR) | ||
return f | ||
} | ||
func (f *FieldQ) SetD() *FieldQ { | ||
f.Field.Set(d) | ||
return f | ||
} | ||
func (f *FieldQ) SetD2() *FieldQ { | ||
f.Field.Set(d2) | ||
return f | ||
} | ||
|
||
func (f *FieldQ) FromBytes(byt [64]byte) *FieldQ { | ||
f.Field.FromBytes(byt, INV, qMod, r2, r3) | ||
return f | ||
} | ||
|
||
func (f *FieldQ) PowVarTime(b [4]uint64) *FieldQ { | ||
f.Field.PowVarTime(b, montR, INV, qMod) | ||
return f | ||
} | ||
|
||
func (f *FieldQ) LegendreSymbolVarTime() *FieldQ { | ||
// Legendre symbol computed via Euler's criterion: | ||
// self^((q - 1) // 2) | ||
f.PowVarTime([4]uint64{ | ||
0x7fffffff80000000, | ||
0xa9ded2017fff2dff, | ||
0x199cec0404d0ec02, | ||
0x39f6d3a994cebea4, | ||
}) | ||
return f | ||
} | ||
|
||
func (f *FieldQ) SqrtVarTime() (*FieldQ, error) { | ||
one := &FieldQ{field.Field{0, 0, 0, 0}} | ||
one.Set(FieldQ{montR}) | ||
zero := &FieldQ{field.Field{0, 0, 0, 0}} | ||
tmp := &FieldQ{field.Field{0, 0, 0, 0}} | ||
|
||
*tmp = *f | ||
|
||
lgs := tmp.LegendreSymbolVarTime() | ||
|
||
if field.Equal(lgs.Field, zero.Field) { | ||
return f, nil | ||
} | ||
if !field.Equal(lgs.Field, one.Field) { | ||
return f, errors.New("legendre symbol does not equal one, sqrt not found") // XXX: We should bubble up an error for this | ||
} | ||
|
||
*tmp = *f | ||
r := *tmp.PowVarTime([4]uint64{0x7fff2dff80000000, 0x04d0ec02a9ded201, 0x94cebea4199cec04, 0x0000000039f6d3a9}) | ||
|
||
*tmp = *f | ||
t := *tmp.PowVarTime([4]uint64{0xfffe5bfeffffffff, 0x09a1d80553bda402, 0x299d7d483339d808, 0x0000000073eda753}) | ||
|
||
c := FieldQ{rootOfUnity} | ||
m := S | ||
|
||
for !field.Equal(t.Field, one.Field) { | ||
|
||
var i = uint32(1) | ||
|
||
t2i := FieldQ{field.Field{0, 0, 0, 0}} | ||
t2i.Square(t) | ||
|
||
for !field.Equal(t2i.Field, one.Field) { | ||
t2i.Square(t2i) | ||
i++ | ||
} | ||
|
||
for k := uint32(0); k < m-i-1; k++ { | ||
c.Square(c) | ||
} | ||
|
||
r.Mul(r, c) | ||
c.Square(c) | ||
t.Mul(t, c) | ||
m = i | ||
|
||
} | ||
|
||
*f = r | ||
|
||
return f, nil | ||
} | ||
|
||
// Rand returns a random field element | ||
func (f *FieldQ) Rand() *FieldQ { | ||
var buf [64]byte | ||
rand.Read(buf[:]) | ||
f.FromBytes(buf) | ||
return f | ||
} | ||
|
||
// FromU64 converts a uint64 into a field element | ||
func (f *FieldQ) FromU64(a uint64) *FieldQ { | ||
f.Field.FromU64(a, INV, r2, qMod) | ||
return f | ||
} | ||
|
||
// Sub Subtracts one field from another | ||
func (f *FieldQ) Sub(a, b FieldQ) *FieldQ { | ||
f.Field.Sub(a.Field, b.Field, qMod) | ||
return f | ||
} | ||
|
||
// Add adds one field from another | ||
func (f *FieldQ) Add(a, b FieldQ) *FieldQ { | ||
f.Field.Add(a.Field, b.Field, qMod) | ||
return f | ||
} | ||
|
||
// Double doubles the field element | ||
func (f *FieldQ) Double() *FieldQ { | ||
f.Field.Double(qMod) | ||
return f | ||
} | ||
|
||
// Mul multiplies one field from another | ||
func (f *FieldQ) Mul(a, b FieldQ) *FieldQ { | ||
f.Field.Mul(a.Field, b.Field, INV, qMod) | ||
return f | ||
} | ||
|
||
// Square squares a field. | ||
func (f *FieldQ) Square(a FieldQ) *FieldQ { | ||
f.Field.Square(a.Field, INV, qMod) | ||
return f | ||
} | ||
|
||
// Neg negates a field. | ||
func (f *FieldQ) Neg(a FieldQ) *FieldQ { | ||
f.Field.Neg(a.Field, qMod) | ||
return f | ||
} | ||
|
||
func (f *FieldQ) String() string { | ||
var s [32]byte | ||
f.BytesInto(&s) | ||
|
||
// reverse bytes | ||
for i, j := 0, len(s)-1; i <= j; i, j = i+1, j-1 { | ||
s[i], s[j] = s[j], s[i] | ||
} | ||
|
||
return "0x" + hex.EncodeToString(s[:]) | ||
} | ||
|
||
// Inverse inverts a field element | ||
// If element is zero, it will return nil | ||
func (f *FieldQ) Inverse(a FieldQ) *FieldQ { | ||
|
||
// Check if a is non-zero | ||
if field.Equal(a.Field, field.Zero) { | ||
return nil | ||
} | ||
|
||
var sqrMulti = func(e *FieldQ, n uint64) { | ||
for i := uint64(0); i < n; i++ { | ||
e.Square(*e) | ||
} | ||
} | ||
|
||
var t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17 FieldQ | ||
|
||
t10 = a | ||
t0.Square(t10) | ||
t1.Mul(t0, t10) | ||
t16.Square(t0) | ||
t6.Square(t16) | ||
t5.Mul(t6, t0) | ||
t0.Mul(t6, t16) | ||
t12.Mul(t5, t16) | ||
t2.Square(t6) | ||
t7.Mul(t5, t6) | ||
t15.Mul(t0, t5) | ||
t17.Square(t12) | ||
t1.Mul(t1, t17) | ||
t3.Mul(t7, t2) | ||
t8.Mul(t1, t17) | ||
t4.Mul(t8, t2) | ||
t9.Mul(t8, t7) | ||
t7.Mul(t4, t5) | ||
t11.Mul(t4, t17) | ||
t5.Mul(t9, t17) | ||
t14.Mul(t7, t15) | ||
t13.Mul(t11, t12) | ||
t12.Mul(t11, t17) | ||
t15.Mul(t15, t12) | ||
t16.Mul(t16, t15) | ||
t3.Mul(t3, t16) | ||
t17.Mul(t17, t3) | ||
t0.Mul(t0, t17) | ||
t6.Mul(t6, t0) | ||
t2.Mul(t2, t6) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t17) | ||
sqrMulti(&t0, 9) | ||
t0.Mul(t0, t16) | ||
sqrMulti(&t0, 9) | ||
t0.Mul(t0, t15) | ||
sqrMulti(&t0, 9) | ||
t0.Mul(t0, t15) | ||
sqrMulti(&t0, 7) | ||
t0.Mul(t0, t14) | ||
sqrMulti(&t0, 7) | ||
t0.Mul(t0, t13) | ||
sqrMulti(&t0, 10) | ||
t0.Mul(t0, t12) | ||
sqrMulti(&t0, 9) | ||
t0.Mul(t0, t11) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t8) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t10) | ||
sqrMulti(&t0, 14) | ||
t0.Mul(t0, t9) | ||
sqrMulti(&t0, 10) | ||
t0.Mul(t0, t8) | ||
sqrMulti(&t0, 15) | ||
t0.Mul(t0, t7) | ||
sqrMulti(&t0, 10) | ||
t0.Mul(t0, t6) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t5) | ||
sqrMulti(&t0, 16) | ||
t0.Mul(t0, t3) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 7) | ||
t0.Mul(t0, t4) | ||
sqrMulti(&t0, 9) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t3) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t3) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 8) | ||
t0.Mul(t0, t2) | ||
sqrMulti(&t0, 5) | ||
t0.Mul(t0, t1) | ||
sqrMulti(&t0, 5) | ||
t0.Mul(t0, t1) | ||
|
||
*f = t0 | ||
|
||
f.Field[0] = t0.Field[0] | ||
f.Field[1] = t0.Field[1] | ||
f.Field[2] = t0.Field[2] | ||
f.Field[3] = t0.Field[3] | ||
|
||
return f | ||
} |
Oops, something went wrong.