http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/FP12.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/FP12.go b/go/amcl-go/FP12.go deleted file mode 100644 index 8e9cb4c..0000000 --- a/go/amcl-go/FP12.go +++ /dev/null @@ -1,654 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL Fp^12 functions */ -/* FP12 elements are of the form a+i.b+i^2.c */ - -package amcl - -//import "fmt" - -type FP12 struct { - a *FP4 - b *FP4 - c *FP4 -} - -/* Constructors */ -func NewFP12fp4(d *FP4) *FP12 { - F := new(FP12) - F.a = NewFP4copy(d) - F.b = NewFP4int(0) - F.c = NewFP4int(0) - return F -} - -func NewFP12int(d int) *FP12 { - F := new(FP12) - F.a = NewFP4int(d) - F.b = NewFP4int(0) - F.c = NewFP4int(0) - return F -} - -func NewFP12fp4s(d *FP4, e *FP4, f *FP4) *FP12 { - F := new(FP12) - F.a = NewFP4copy(d) - F.b = NewFP4copy(e) - F.c = NewFP4copy(f) - return F -} - -func NewFP12copy(x *FP12) *FP12 { - F := new(FP12) - F.a = NewFP4copy(x.a) - F.b = NewFP4copy(x.b) - F.c = NewFP4copy(x.c) - return F -} - -/* reduce all components of this mod Modulus */ -func (F *FP12) reduce() { - F.a.reduce() - F.b.reduce() - F.c.reduce() -} - -/* normalise all components of this */ -func (F *FP12) norm() { - F.a.norm() - F.b.norm() - F.c.norm() -} - -/* test x==0 ? */ -func (F *FP12) iszilch() bool { - F.reduce() - return (F.a.iszilch() && F.b.iszilch() && F.c.iszilch()) -} - -/* test x==1 ? */ -func (F *FP12) isunity() bool { - one := NewFP4int(1) - return (F.a.equals(one) && F.b.iszilch() && F.c.iszilch()) -} - -/* return 1 if x==y, else 0 */ -func (F *FP12) equals(x *FP12) bool { - return (F.a.equals(x.a) && F.b.equals(x.b) && F.c.equals(x.c)) -} - -/* extract a from this */ -func (F *FP12) geta() *FP4 { - return F.a -} - -/* extract b */ -func (F *FP12) getb() *FP4 { - return F.b -} - -/* extract c */ -func (F *FP12) getc() *FP4 { - return F.c -} - -/* copy this=x */ -func (F *FP12) copy(x *FP12) { - F.a.copy(x.a) - F.b.copy(x.b) - F.c.copy(x.c) -} - -/* set this=1 */ -func (F *FP12) one() { - F.a.one() - F.b.zero() - F.c.zero() -} - -/* this=conj(this) */ -func (F *FP12) conj() { - F.a.conj() - F.b.nconj() - F.c.conj() -} - -/* Granger-Scott Unitary Squaring */ -func (F *FP12) usqr() { - A := NewFP4copy(F.a) - B := NewFP4copy(F.c) - C := NewFP4copy(F.b) - D := NewFP4int(0) - - F.a.sqr() - D.copy(F.a) - D.add(F.a) - F.a.add(D) - - // a.norm(); - A.nconj() - - A.add(A) - F.a.add(A) - B.sqr() - B.times_i() - - D.copy(B) - D.add(B) - B.add(D) - // B.norm(); - - C.sqr() - D.copy(C) - D.add(C) - C.add(D) - // C.norm(); - - F.b.conj() - F.b.add(F.b) - F.c.nconj() - - F.c.add(F.c) - F.b.add(B) - F.c.add(C) - F.reduce() - -} - -/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ -func (F *FP12) sqr() { - A := NewFP4copy(F.a) - B := NewFP4copy(F.b) - C := NewFP4copy(F.c) - D := NewFP4copy(F.a) - - A.sqr() - B.mul(F.c) - B.add(B) - C.sqr() - D.mul(F.b) - D.add(D) - - F.c.add(F.a) - F.c.add(F.b) - F.c.sqr() - - F.a.copy(A) - - A.add(B) - // A.norm(); - A.add(C) - A.add(D) - // A.norm(); - - A.neg() - B.times_i() - C.times_i() - - F.a.add(B) - - F.b.copy(C) - F.b.add(D) - F.c.add(A) - F.norm() -} - -/* FP12 full multiplication this=this*y */ -func (F *FP12) mul(y *FP12) { - z0 := NewFP4copy(F.a) - z1 := NewFP4int(0) - z2 := NewFP4copy(F.b) - z3 := NewFP4int(0) - t0 := NewFP4copy(F.a) - t1 := NewFP4copy(y.a) - - z0.mul(y.a) - z2.mul(y.b) - - t0.add(F.b) - t1.add(y.b) - - z1.copy(t0) - z1.mul(t1) - t0.copy(F.b) - t0.add(F.c) - - t1.copy(y.b) - t1.add(y.c) - z3.copy(t0) - z3.mul(t1) - - t0.copy(z0) - t0.neg() - t1.copy(z2) - t1.neg() - - z1.add(t0) - // z1.norm(); - F.b.copy(z1) - F.b.add(t1) - - z3.add(t1) - z2.add(t0) - - t0.copy(F.a) - t0.add(F.c) - t1.copy(y.a) - t1.add(y.c) - t0.mul(t1) - z2.add(t0) - - t0.copy(F.c) - t0.mul(y.c) - t1.copy(t0) - t1.neg() - - // z2.norm(); - // z3.norm(); - // b.norm(); - - F.c.copy(z2) - F.c.add(t1) - z3.add(t1) - t0.times_i() - F.b.add(t0) - - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - F.norm() -} - -/* Special case of multiplication arises from special form of ATE pairing line function */ -func (F *FP12) smul(y *FP12) { - z0 := NewFP4copy(F.a) - z2 := NewFP4copy(F.b) - z3 := NewFP4copy(F.b) - t0 := NewFP4int(0) - t1 := NewFP4copy(y.a) - - z0.mul(y.a) - z2.pmul(y.b.real()) - F.b.add(F.a) - t1.real().add(y.b.real()) - - F.b.mul(t1) - z3.add(F.c) - z3.pmul(y.b.real()) - - t0.copy(z0) - t0.neg() - t1.copy(z2) - t1.neg() - - F.b.add(t0) - // b.norm(); - - F.b.add(t1) - z3.add(t1) - z2.add(t0) - - t0.copy(F.a) - t0.add(F.c) - t0.mul(y.a) - F.c.copy(z2) - F.c.add(t0) - - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - - F.norm() -} - -/* this=1/this */ -func (F *FP12) inverse() { - f0 := NewFP4copy(F.a) - f1 := NewFP4copy(F.b) - f2 := NewFP4copy(F.a) - f3 := NewFP4int(0) - - F.norm() - f0.sqr() - f1.mul(F.c) - f1.times_i() - f0.sub(f1) - - f1.copy(F.c) - f1.sqr() - f1.times_i() - f2.mul(F.b) - f1.sub(f2) - - f2.copy(F.b) - f2.sqr() - f3.copy(F.a) - f3.mul(F.c) - f2.sub(f3) - - f3.copy(F.b) - f3.mul(f2) - f3.times_i() - F.a.mul(f0) - f3.add(F.a) - F.c.mul(f1) - F.c.times_i() - - f3.add(F.c) - f3.inverse() - F.a.copy(f0) - F.a.mul(f3) - F.b.copy(f1) - F.b.mul(f3) - F.c.copy(f2) - F.c.mul(f3) -} - -/* this=this^p using Frobenius */ -func (F *FP12) frob(f *FP2) { - f2 := NewFP2copy(f) - f3 := NewFP2copy(f) - - f2.sqr() - f3.mul(f2) - - F.a.frob(f3) - F.b.frob(f3) - F.c.frob(f3) - - F.b.pmul(f) - F.c.pmul(f2) -} - -/* trace function */ -func (F *FP12) trace() *FP4 { - t := NewFP4int(0) - t.copy(F.a) - t.imul(3) - t.reduce() - return t -} - -/* convert from byte array to FP12 */ -func FP12_fromBytes(w []byte) *FP12 { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - - for i := 0; i < MB; i++ { - t[i] = w[i] - } - a := fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+MB] - } - b := fromBytes(t[:]) - c := NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+2*MB] - } - a = fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+3*MB] - } - b = fromBytes(t[:]) - d := NewFP2bigs(a, b) - - e := NewFP4fp2s(c, d) - - for i := 0; i < MB; i++ { - t[i] = w[i+4*MB] - } - a = fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+5*MB] - } - b = fromBytes(t[:]) - c = NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+6*MB] - } - a = fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+7*MB] - } - b = fromBytes(t[:]) - d = NewFP2bigs(a, b) - - f := NewFP4fp2s(c, d) - - for i := 0; i < MB; i++ { - t[i] = w[i+8*MB] - } - a = fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+9*MB] - } - b = fromBytes(t[:]) - - c = NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+10*MB] - } - a = fromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+11*MB] - } - b = fromBytes(t[:]) - d = NewFP2bigs(a, b) - - g := NewFP4fp2s(c, d) - - return NewFP12fp4s(e, f, g) -} - -/* convert this to byte array */ -func (F *FP12) toBytes(w []byte) { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - F.a.geta().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i] = t[i] - } - F.a.geta().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+MB] = t[i] - } - F.a.getb().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+2*MB] = t[i] - } - F.a.getb().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+3*MB] = t[i] - } - - F.b.geta().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+4*MB] = t[i] - } - F.b.geta().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+5*MB] = t[i] - } - F.b.getb().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+6*MB] = t[i] - } - F.b.getb().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+7*MB] = t[i] - } - - F.c.geta().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+8*MB] = t[i] - } - F.c.geta().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+9*MB] = t[i] - } - F.c.getb().getA().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+10*MB] = t[i] - } - F.c.getb().getB().toBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+11*MB] = t[i] - } -} - -/* convert to hex string */ -func (F *FP12) toString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "," + F.c.toString() + "]") -} - -/* this=this^e */ -func (F *FP12) pow(e *BIG) *FP12 { - F.norm() - e.norm() - w := NewFP12copy(F) - z := NewBIGcopy(e) - r := NewFP12int(1) - - for true { - bt := z.parity() - z.fshr(1) - if bt == 1 { - r.mul(w) - } - if z.iszilch() { - break - } - w.usqr() - } - r.reduce() - return r -} - -/* constant time powering by small integer of max length bts */ -func (F *FP12) pinpow(e int, bts int) { - var R []*FP12 - R = append(R, NewFP12int(1)) - R = append(R, NewFP12copy(F)) - - for i := bts - 1; i >= 0; i-- { - b := (e >> uint(i)) & 1 - R[1-b].mul(R[b]) - R[b].usqr() - } - F.copy(R[0]) -} - -/* p=q0^u0.q1^u1.q2^u2.q3^u3 */ -/* Timing attack secure, but not cache attack secure */ - -func pow4(q []*FP12, u []*BIG) *FP12 { - var a [4]int8 - var g []*FP12 - var s []*FP12 - c := NewFP12int(1) - p := NewFP12int(0) - var w [NLEN*int(BASEBITS) + 1]int8 - var t []*BIG - mt := NewBIGint(0) - - for i := 0; i < 4; i++ { - t = append(t, NewBIGcopy(u[i])) - } - - s = append(s, NewFP12int(0)) - s = append(s, NewFP12int(0)) - - g = append(g, NewFP12copy(q[0])) - s[0].copy(q[1]) - s[0].conj() - g[0].mul(s[0]) - g = append(g, NewFP12copy(g[0])) - g = append(g, NewFP12copy(g[0])) - g = append(g, NewFP12copy(g[0])) - g = append(g, NewFP12copy(q[0])) - g[4].mul(q[1]) - g = append(g, NewFP12copy(g[4])) - g = append(g, NewFP12copy(g[4])) - g = append(g, NewFP12copy(g[4])) - - s[1].copy(q[2]) - s[0].copy(q[3]) - s[0].conj() - s[1].mul(s[0]) - s[0].copy(s[1]) - s[0].conj() - g[1].mul(s[0]) - g[2].mul(s[1]) - g[5].mul(s[0]) - g[6].mul(s[1]) - s[1].copy(q[2]) - s[1].mul(q[3]) - s[0].copy(s[1]) - s[0].conj() - g[0].mul(s[0]) - g[3].mul(s[1]) - g[4].mul(s[0]) - g[7].mul(s[1]) - - /* if power is even add 1 to power, and add q to correction */ - - for i := 0; i < 4; i++ { - if t[i].parity() == 0 { - t[i].inc(1) - t[i].norm() - c.mul(q[i]) - } - mt.add(t[i]) - mt.norm() - } - c.conj() - nb := 1 + mt.nbits() - - /* convert exponent to signed 1-bit window */ - for j := 0; j < nb; j++ { - for i := 0; i < 4; i++ { - a[i] = int8(t[i].lastbits(2) - 2) - t[i].dec(int(a[i])) - t[i].norm() - t[i].fshr(1) - } - w[j] = (8*a[0] + 4*a[1] + 2*a[2] + a[3]) - } - w[nb] = int8(8*t[0].lastbits(2) + 4*t[1].lastbits(2) + 2*t[2].lastbits(2) + t[3].lastbits(2)) - p.copy(g[(w[nb]-1)/2]) - - for i := nb - 1; i >= 0; i-- { - m := w[i] >> 7 - j := (w[i] ^ m) - m /* j=abs(w[i]) */ - j = (j - 1) / 2 - s[0].copy(g[j]) - s[1].copy(g[j]) - s[1].conj() - p.usqr() - p.mul(s[m&1]) - } - p.mul(c) /* apply correction */ - p.reduce() - return p -}
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/FP2.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/FP2.go b/go/amcl-go/FP2.go deleted file mode 100644 index 599fbcc..0000000 --- a/go/amcl-go/FP2.go +++ /dev/null @@ -1,324 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Finite Field arithmetic Fp^2 functions */ - -/* FP2 elements are of the form a+ib, where i is sqrt(-1) */ - -package amcl - -//import "fmt" - -type FP2 struct { - a *FP - b *FP -} - -/* Constructors */ -func NewFP2int(a int) *FP2 { - F := new(FP2) - F.a = NewFPint(a) - F.b = NewFPint(0) - return F -} - -func NewFP2copy(x *FP2) *FP2 { - F := new(FP2) - F.a = NewFPcopy(x.a) - F.b = NewFPcopy(x.b) - return F -} - -func NewFP2fps(c *FP, d *FP) *FP2 { - F := new(FP2) - F.a = NewFPcopy(c) - F.b = NewFPcopy(d) - return F -} - -func NewFP2bigs(c *BIG, d *BIG) *FP2 { - F := new(FP2) - F.a = NewFPbig(c) - F.b = NewFPbig(d) - return F -} - -func NewFP2fp(c *FP) *FP2 { - F := new(FP2) - F.a = NewFPcopy(c) - F.b = NewFPint(0) - return F -} - -func NewFP2big(c *BIG) *FP2 { - F := new(FP2) - F.a = NewFPbig(c) - F.b = NewFPint(0) - return F -} - -/* reduce components mod Modulus */ -func (F *FP2) reduce() { - F.a.reduce() - F.b.reduce() -} - -/* normalise components of w */ -func (F *FP2) norm() { - F.a.norm() - F.b.norm() -} - -/* test this=0 ? */ -func (F *FP2) iszilch() bool { - F.reduce() - return (F.a.iszilch() && F.b.iszilch()) -} - -func (F *FP2) cmove(g *FP2, d int32) { - F.a.cmove(g.a, d) - F.b.cmove(g.b, d) -} - -/* test this=1 ? */ -func (F *FP2) isunity() bool { - one := NewFPint(1) - return (F.a.equals(one) && F.b.iszilch()) -} - -/* test this=x */ -func (F *FP2) equals(x *FP2) bool { - return (F.a.equals(x.a) && F.b.equals(x.b)) -} - -/* extract a */ -func (F *FP2) getA() *BIG { - return F.a.redc() -} - -/* extract b */ -func (F *FP2) getB() *BIG { - return F.b.redc() -} - -/* copy this=x */ -func (F *FP2) copy(x *FP2) { - F.a.copy(x.a) - F.b.copy(x.b) -} - -/* set this=0 */ -func (F *FP2) zero() { - F.a.zero() - F.b.zero() -} - -/* set this=1 */ -func (F *FP2) one() { - F.a.one() - F.b.zero() -} - -/* negate this mod Modulus */ -func (F *FP2) neg() { - F.norm() - m := NewFPcopy(F.a) - t := NewFPint(0) - - m.add(F.b) - m.neg() - m.norm() - t.copy(m) - t.add(F.b) - F.b.copy(m) - F.b.add(F.a) - F.a.copy(t) -} - -/* set to a-ib */ -func (F *FP2) conj() { - F.b.neg() -} - -/* this+=a */ -func (F *FP2) add(x *FP2) { - F.a.add(x.a) - F.b.add(x.b) -} - -/* this-=a */ -func (F *FP2) sub(x *FP2) { - m := NewFP2copy(x) - m.neg() - F.add(m) -} - -/* this*=s, where s is an FP */ -func (F *FP2) pmul(s *FP) { - F.a.mul(s) - F.b.mul(s) -} - -/* this*=i, where i is an int */ -func (F *FP2) imul(c int) { - F.a.imul(c) - F.b.imul(c) -} - -/* this*=this */ -func (F *FP2) sqr() { - F.norm() - w1 := NewFPcopy(F.a) - w3 := NewFPcopy(F.a) - mb := NewFPcopy(F.b) - - w3.mul(F.b) - w1.add(F.b) - mb.neg() - F.a.add(mb) - F.a.mul(w1) - F.b.copy(w3) - F.b.add(w3) - - F.norm() -} - -/* this*=y */ -func (F *FP2) mul(y *FP2) { - F.norm() /* This is needed here as {a,b} is not normed before additions */ - - w1 := NewFPcopy(F.a) - w2 := NewFPcopy(F.b) - w5 := NewFPcopy(F.a) - mw := NewFPint(0) - - w1.mul(y.a) // w1=a*y.a - this norms w1 and y.a, NOT a - w2.mul(y.b) // w2=b*y.b - this norms w2 and y.b, NOT b - w5.add(F.b) // w5=a+b - F.b.copy(y.a) - F.b.add(y.b) // b=y.a+y.b - - F.b.mul(w5) - mw.copy(w1) - mw.add(w2) - mw.neg() - - F.b.add(mw) - mw.add(w1) - F.a.copy(w1) - F.a.add(mw) - - F.norm() -} - -/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ -/* returns true if this is QR */ -func (F *FP2) sqrt() bool { - if F.iszilch() { - return true - } - w1 := NewFPcopy(F.b) - w2 := NewFPcopy(F.a) - w1.sqr() - w2.sqr() - w1.add(w2) - if w1.jacobi() != 1 { - F.zero() - return false - } - w1 = w1.sqrt() - w2.copy(F.a) - w2.add(w1) - w2.div2() - if w2.jacobi() != 1 { - w2.copy(F.a) - w2.sub(w1) - w2.div2() - if w2.jacobi() != 1 { - F.zero() - return false - } - } - w2 = w2.sqrt() - F.a.copy(w2) - w2.add(w2) - w2.inverse() - F.b.mul(w2) - return true -} - -/* output to hex string */ -func (F *FP2) toString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "]") -} - -/* this=1/this */ -func (F *FP2) inverse() { - F.norm() - w1 := NewFPcopy(F.a) - w2 := NewFPcopy(F.b) - - w1.sqr() - w2.sqr() - w1.add(w2) - w1.inverse() - F.a.mul(w1) - w1.neg() - F.b.mul(w1) -} - -/* this/=2 */ -func (F *FP2) div2() { - F.a.div2() - F.b.div2() -} - -/* this*=sqrt(-1) */ -func (F *FP2) times_i() { - // a.norm(); - z := NewFPcopy(F.a) - F.a.copy(F.b) - F.a.neg() - F.b.copy(z) -} - -/* w*=(1+sqrt(-1)) */ -/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */ -func (F *FP2) mul_ip() { - F.norm() - t := NewFP2copy(F) - z := NewFPcopy(F.a) - F.a.copy(F.b) - F.a.neg() - F.b.copy(z) - F.add(t) - F.norm() -} - -/* w/=(1+sqrt(-1)) */ -func (F *FP2) div_ip() { - t := NewFP2int(0) - F.norm() - t.a.copy(F.a) - t.a.add(F.b) - t.b.copy(F.b) - t.b.sub(F.a) - F.copy(t) - F.div2() -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/FP4.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/FP4.go b/go/amcl-go/FP4.go deleted file mode 100644 index 76e9d1e..0000000 --- a/go/amcl-go/FP4.go +++ /dev/null @@ -1,522 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Finite Field arithmetic Fp^4 functions */ - -/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1)) */ - -package amcl - -//import "fmt" - -type FP4 struct { - a *FP2 - b *FP2 -} - -/* Constructors */ -func NewFP4int(a int) *FP4 { - F := new(FP4) - F.a = NewFP2int(a) - F.b = NewFP2int(0) - return F -} - -func NewFP4copy(x *FP4) *FP4 { - F := new(FP4) - F.a = NewFP2copy(x.a) - F.b = NewFP2copy(x.b) - return F -} - -func NewFP4fp2s(c *FP2, d *FP2) *FP4 { - F := new(FP4) - F.a = NewFP2copy(c) - F.b = NewFP2copy(d) - return F -} - -func NewFP4fp2(c *FP2) *FP4 { - F := new(FP4) - F.a = NewFP2copy(c) - F.b = NewFP2int(0) - return F -} - -/* reduce all components of this mod Modulus */ -func (F *FP4) reduce() { - F.a.reduce() - F.b.reduce() -} - -/* normalise all components of this mod Modulus */ -func (F *FP4) norm() { - F.a.norm() - F.b.norm() -} - -/* test this==0 ? */ -func (F *FP4) iszilch() bool { - F.reduce() - return F.a.iszilch() && F.b.iszilch() -} - -/* test this==1 ? */ -func (F *FP4) isunity() bool { - one := NewFP2int(1) - return F.a.equals(one) && F.b.iszilch() -} - -/* test is w real? That is in a+ib test b is zero */ -func (F *FP4) isreal() bool { - return F.b.iszilch() -} - -/* extract real part a */ -func (F *FP4) real() *FP2 { - return F.a -} - -func (F *FP4) geta() *FP2 { - return F.a -} - -/* extract imaginary part b */ -func (F *FP4) getb() *FP2 { - return F.b -} - -/* test this=x? */ -func (F *FP4) equals(x *FP4) bool { - return (F.a.equals(x.a) && F.b.equals(x.b)) -} - -/* copy this=x */ -func (F *FP4) copy(x *FP4) { - F.a.copy(x.a) - F.b.copy(x.b) -} - -/* set this=0 */ -func (F *FP4) zero() { - F.a.zero() - F.b.zero() -} - -/* set this=1 */ -func (F *FP4) one() { - F.a.one() - F.b.zero() -} - -/* set this=-this */ -func (F *FP4) neg() { - m := NewFP2copy(F.a) - t := NewFP2int(0) - m.add(F.b) - m.neg() - m.norm() - t.copy(m) - t.add(F.b) - F.b.copy(m) - F.b.add(F.a) - F.a.copy(t) -} - -/* this=conjugate(this) */ -func (F *FP4) conj() { - F.b.neg() - F.b.norm() -} - -/* this=-conjugate(this) */ -func (F *FP4) nconj() { - F.a.neg() - F.a.norm() -} - -/* this+=x */ -func (F *FP4) add(x *FP4) { - F.a.add(x.a) - F.b.add(x.b) -} - -/* this-=x */ -func (F *FP4) sub(x *FP4) { - m := NewFP4copy(x) - m.neg() - F.add(m) -} - -/* this*=s where s is FP2 */ -func (F *FP4) pmul(s *FP2) { - F.a.mul(s) - F.b.mul(s) -} - -/* this*=c where c is int */ -func (F *FP4) imul(c int) { - F.a.imul(c) - F.b.imul(c) -} - -/* this*=this */ -func (F *FP4) sqr() { - F.norm() - - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - t3 := NewFP2copy(F.a) - - t3.mul(F.b) - t1.add(F.b) - t2.mul_ip() - - t2.add(F.a) - F.a.copy(t1) - - F.a.mul(t2) - - t2.copy(t3) - t2.mul_ip() - t2.add(t3) - t2.neg() - F.a.add(t2) - - F.b.copy(t3) - F.b.add(t3) - - F.norm() -} - -/* this*=y */ -func (F *FP4) mul(y *FP4) { - F.norm() - - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - t3 := NewFP2int(0) - t4 := NewFP2copy(F.b) - - t1.mul(y.a) - t2.mul(y.b) - t3.copy(y.b) - t3.add(y.a) - t4.add(F.a) - - t4.mul(t3) - t4.sub(t1) - // t4.norm(); - - F.b.copy(t4) - F.b.sub(t2) - t2.mul_ip() - F.a.copy(t2) - F.a.add(t1) - - F.norm() -} - -/* convert this to hex string */ -func (F *FP4) toString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "]") -} - -/* this=1/this */ -func (F *FP4) inverse() { - F.norm() - - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - - t1.sqr() - t2.sqr() - t2.mul_ip() - t1.sub(t2) - t1.inverse() - F.a.mul(t1) - t1.neg() - F.b.mul(t1) -} - -/* this*=i where i = sqrt(-1+sqrt(-1)) */ -func (F *FP4) times_i() { - F.norm() - s := NewFP2copy(F.b) - t := NewFP2copy(F.b) - s.times_i() - t.add(s) - // t.norm(); - F.b.copy(F.a) - F.a.copy(t) -} - -/* this=this^p using Frobenius */ -func (F *FP4) frob(f *FP2) { - F.a.conj() - F.b.conj() - F.b.mul(f) -} - -/* this=this^e */ -func (F *FP4) pow(e *BIG) *FP4 { - F.norm() - e.norm() - w := NewFP4copy(F) - z := NewBIGcopy(e) - r := NewFP4int(1) - for true { - bt := z.parity() - z.fshr(1) - if bt == 1 { - r.mul(w) - } - if z.iszilch() { - break - } - w.sqr() - } - r.reduce() - return r -} - -/* XTR xtr_a function */ -func (F *FP4) xtr_A(w *FP4, y *FP4, z *FP4) { - r := NewFP4copy(w) - t := NewFP4copy(w) - r.sub(y) - r.pmul(F.a) - t.add(y) - t.pmul(F.b) - t.times_i() - - F.copy(r) - F.add(t) - F.add(z) - - F.norm() -} - -/* XTR xtr_d function */ -func (F *FP4) xtr_D() { - w := NewFP4copy(F) - F.sqr() - w.conj() - w.add(w) - F.sub(w) - F.reduce() -} - -/* r=x^n using XTR method on traces of FP12s */ -func (F *FP4) xtr_pow(n *BIG) *FP4 { - a := NewFP4int(3) - b := NewFP4copy(F) - c := NewFP4copy(b) - c.xtr_D() - t := NewFP4int(0) - r := NewFP4int(0) - - n.norm() - par := n.parity() - v := NewBIGcopy(n) - v.fshr(1) - if par == 0 { - v.dec(1) - v.norm() - } - - nb := v.nbits() - for i := nb - 1; i >= 0; i-- { - if v.bit(i) != 1 { - t.copy(b) - F.conj() - c.conj() - b.xtr_A(a, F, c) - F.conj() - c.copy(t) - c.xtr_D() - a.xtr_D() - } else { - t.copy(a) - t.conj() - a.copy(b) - a.xtr_D() - b.xtr_A(c, F, t) - c.xtr_D() - } - } - if par == 0 { - r.copy(c) - } else { - r.copy(b) - } - r.reduce() - return r -} - -/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */ -func (F *FP4) xtr_pow2(ck *FP4, ckml *FP4, ckm2l *FP4, a *BIG, b *BIG) *FP4 { - a.norm() - b.norm() - e := NewBIGcopy(a) - d := NewBIGcopy(b) - w := NewBIGint(0) - - cu := NewFP4copy(ck) // can probably be passed in w/o copying - cv := NewFP4copy(F) - cumv := NewFP4copy(ckml) - cum2v := NewFP4copy(ckm2l) - r := NewFP4int(0) - t := NewFP4int(0) - - f2 := 0 - for d.parity() == 0 && e.parity() == 0 { - d.fshr(1) - e.fshr(1) - f2++ - } - - for comp(d, e) != 0 { - if comp(d, e) > 0 { - w.copy(e) - w.imul(4) - w.norm() - if comp(d, w) <= 0 { - w.copy(d) - d.copy(e) - e.rsub(w) - e.norm() - - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cum2v.copy(cumv) - cum2v.conj() - cumv.copy(cv) - cv.copy(cu) - cu.copy(t) - } else { - if d.parity() == 0 { - d.fshr(1) - r.copy(cum2v) - r.conj() - t.copy(cumv) - t.xtr_A(cu, cv, r) - cum2v.copy(cumv) - cum2v.xtr_D() - cumv.copy(t) - cu.xtr_D() - } else { - if e.parity() == 1 { - d.sub(e) - d.norm() - d.fshr(1) - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cu.xtr_D() - cum2v.copy(cv) - cum2v.xtr_D() - cum2v.conj() - cv.copy(t) - } else { - w.copy(d) - d.copy(e) - d.fshr(1) - e.copy(w) - t.copy(cumv) - t.xtr_D() - cumv.copy(cum2v) - cumv.conj() - cum2v.copy(t) - cum2v.conj() - t.copy(cv) - t.xtr_D() - cv.copy(cu) - cu.copy(t) - } - } - } - } - if comp(d, e) < 0 { - w.copy(d) - w.imul(4) - w.norm() - if comp(e, w) <= 0 { - e.sub(d) - e.norm() - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cum2v.copy(cumv) - cumv.copy(cu) - cu.copy(t) - } else { - if e.parity() == 0 { - w.copy(d) - d.copy(e) - d.fshr(1) - e.copy(w) - t.copy(cumv) - t.xtr_D() - cumv.copy(cum2v) - cumv.conj() - cum2v.copy(t) - cum2v.conj() - t.copy(cv) - t.xtr_D() - cv.copy(cu) - cu.copy(t) - } else { - if d.parity() == 1 { - w.copy(e) - e.copy(d) - w.sub(d) - w.norm() - d.copy(w) - d.fshr(1) - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cumv.conj() - cum2v.copy(cu) - cum2v.xtr_D() - cum2v.conj() - cu.copy(cv) - cu.xtr_D() - cv.copy(t) - } else { - d.fshr(1) - r.copy(cum2v) - r.conj() - t.copy(cumv) - t.xtr_A(cu, cv, r) - cum2v.copy(cumv) - cum2v.xtr_D() - cumv.copy(t) - cu.xtr_D() - } - } - } - } - } - r.copy(cv) - r.xtr_A(cu, cumv, cum2v) - for i := 0; i < f2; i++ { - r.xtr_D() - } - r = r.xtr_pow(d) - return r -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/GCM.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/GCM.go b/go/amcl-go/GCM.go deleted file mode 100644 index 2fc4da3..0000000 --- a/go/amcl-go/GCM.go +++ /dev/null @@ -1,472 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* -* Implementation of the AES-GCM Encryption/Authentication -* -* Some restrictions.. -* 1. Only for use with AES -* 2. Returned tag is always 128-bits. Truncate at your own risk. -* 3. The order of function calls must follow some rules -* -* Typical sequence of calls.. -* 1. call GCM_init -* 2. call GCM_add_header any number of times, as long as length of header is multiple of 16 bytes (block size) -* 3. call GCM_add_header one last time with any length of header -* 4. call GCM_add_cipher any number of times, as long as length of cipher/plaintext is multiple of 16 bytes -* 5. call GCM_add_cipher one last time with any length of cipher/plaintext -* 6. call GCM_finish to extract the tag. -* -* See http://www.mindspring.com/~dmcgrew/gcm-nist-6.pdf - */ - -package amcl - -/* -import -( - "fmt" - "strconv" -) -*/ -const gcm_NB int = 4 -const GCM_ACCEPTING_HEADER int = 0 -const GCM_ACCEPTING_CIPHER int = 1 -const GCM_NOT_ACCEPTING_MORE int = 2 -const GCM_FINISHED int = 3 -const GCM_ENCRYPTING int = 0 -const GCM_DECRYPTING int = 1 - -type GCM struct { - table [128][4]uint32 /* 2k bytes */ - stateX [16]byte - Y_0 [16]byte - counter int - lenA [2]uint32 - lenC [2]uint32 - status int - a *AES -} - -func gcm_pack(b [4]byte) uint32 { /* pack bytes into a 32-bit Word */ - return ((uint32(b[0]) & 0xff) << 24) | ((uint32(b[1]) & 0xff) << 16) | ((uint32(b[2]) & 0xff) << 8) | (uint32(b[3]) & 0xff) -} - -func gcm_unpack(a uint32) [4]byte { /* unpack bytes from a word */ - var b = [4]byte{byte((a >> 24) & 0xff), byte((a >> 16) & 0xff), byte((a >> 8) & 0xff), byte(a & 0xff)} - return b -} - -func (G *GCM) precompute(H []byte) { - var b [4]byte - j := 0 - for i := 0; i < gcm_NB; i++ { - b[0] = H[j] - b[1] = H[j+1] - b[2] = H[j+2] - b[3] = H[j+3] - G.table[0][i] = gcm_pack(b) - j += 4 - } - for i := 1; i < 128; i++ { - c := uint32(0) - for j := 0; j < gcm_NB; j++ { - G.table[i][j] = c | (G.table[i-1][j])>>1 - c = G.table[i-1][j] << 31 - } - if c != 0 { - G.table[i][0] ^= 0xE1000000 - } /* irreducible polynomial */ - } -} - -func (G *GCM) gf2mul() { /* gf2m mul - Z=H*X mod 2^128 */ - var P [4]uint32 - - for i := 0; i < 4; i++ { - P[i] = 0 - } - j := uint(8) - m := 0 - for i := 0; i < 128; i++ { - j-- - c := (G.stateX[m] >> j) & 1 - if c != 0 { - for k := 0; k < gcm_NB; k++ { - P[k] ^= G.table[i][k] - } - } - if j == 0 { - j = 8 - m++ - if m == 16 { - break - } - } - } - j = 0 - for i := 0; i < gcm_NB; i++ { - b := gcm_unpack(P[i]) - G.stateX[j] = b[0] - G.stateX[j+1] = b[1] - G.stateX[j+2] = b[2] - G.stateX[j+3] = b[3] - j += 4 - } -} - -func (G *GCM) wrap() { /* Finish off GHASH */ - var F [4]uint32 - var L [16]byte - - /* convert lengths from bytes to bits */ - F[0] = (G.lenA[0] << 3) | (G.lenA[1]&0xE0000000)>>29 - F[1] = G.lenA[1] << 3 - F[2] = (G.lenC[0] << 3) | (G.lenC[1]&0xE0000000)>>29 - F[3] = G.lenC[1] << 3 - j := 0 - for i := 0; i < gcm_NB; i++ { - b := gcm_unpack(F[i]) - L[j] = b[0] - L[j+1] = b[1] - L[j+2] = b[2] - L[j+3] = b[3] - j += 4 - } - for i := 0; i < 16; i++ { - G.stateX[i] ^= L[i] - } - G.gf2mul() -} - -func (G *GCM) ghash(plain []byte, len int) bool { - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return false - } - - j := 0 - for j < len { - for i := 0; i < 16 && j < len; i++ { - G.stateX[i] ^= plain[j] - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return true -} - -/* Initialize GCM mode */ -func (G *GCM) Init(key []byte, niv int, iv []byte) { /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */ - var H [16]byte - - for i := 0; i < 16; i++ { - H[i] = 0 - G.stateX[i] = 0 - } - - G.a = new(AES) - - G.a.Init(aes_ECB, key, iv) - G.a.ecb_encrypt(H[:]) /* E(K,0) */ - G.precompute(H[:]) - - G.lenA[0] = 0 - G.lenC[0] = 0 - G.lenA[1] = 0 - G.lenC[1] = 0 - if niv == 12 { - for i := 0; i < 12; i++ { - G.a.f[i] = iv[i] - } - b := gcm_unpack(uint32(1)) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* initialise IV */ - for i := 0; i < 16; i++ { - G.Y_0[i] = G.a.f[i] - } - } else { - G.status = GCM_ACCEPTING_CIPHER - G.ghash(iv, niv) /* GHASH(H,0,IV) */ - G.wrap() - for i := 0; i < 16; i++ { - G.a.f[i] = G.stateX[i] - G.Y_0[i] = G.a.f[i] - G.stateX[i] = 0 - } - G.lenA[0] = 0 - G.lenC[0] = 0 - G.lenA[1] = 0 - G.lenC[1] = 0 - } - G.status = GCM_ACCEPTING_HEADER -} - -/* Add Header data - included but not encrypted */ -func (G *GCM) Add_header(header []byte, len int) bool { /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */ - if G.status != GCM_ACCEPTING_HEADER { - return false - } - - j := 0 - for j < len { - for i := 0; i < 16 && j < len; i++ { - G.stateX[i] ^= header[j] - j++ - G.lenA[1]++ - if G.lenA[1] == 0 { - G.lenA[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_ACCEPTING_CIPHER - } - return true -} - -/* Add Plaintext - included and encrypted */ -func (G *GCM) Add_plain(plain []byte, len int) []byte { - var B [16]byte - var b [4]byte - - cipher := make([]byte, len) - var counter uint32 = 0 - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return nil - } - - j := 0 - for j < len { - - b[0] = G.a.f[12] - b[1] = G.a.f[13] - b[2] = G.a.f[14] - b[3] = G.a.f[15] - counter = gcm_pack(b) - counter++ - b = gcm_unpack(counter) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* increment counter */ - for i := 0; i < 16; i++ { - B[i] = G.a.f[i] - } - G.a.ecb_encrypt(B[:]) /* encrypt it */ - - for i := 0; i < 16 && j < len; i++ { - cipher[j] = (plain[j] ^ B[i]) - G.stateX[i] ^= cipher[j] - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return cipher -} - -/* Add Ciphertext - decrypts to plaintext */ -func (G *GCM) Add_cipher(cipher []byte, len int) []byte { - var B [16]byte - var b [4]byte - - plain := make([]byte, len) - var counter uint32 = 0 - - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return nil - } - - j := 0 - for j < len { - b[0] = G.a.f[12] - b[1] = G.a.f[13] - b[2] = G.a.f[14] - b[3] = G.a.f[15] - counter = gcm_pack(b) - counter++ - b = gcm_unpack(counter) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* increment counter */ - for i := 0; i < 16; i++ { - B[i] = G.a.f[i] - } - G.a.ecb_encrypt(B[:]) /* encrypt it */ - for i := 0; i < 16 && j < len; i++ { - plain[j] = (cipher[j] ^ B[i]) - G.stateX[i] ^= cipher[j] - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return plain -} - -/* Finish and extract Tag */ -func (G *GCM) Finish(extract bool) [16]byte { /* Finish off GHASH and extract tag (MAC) */ - var tag [16]byte - - G.wrap() - /* extract tag */ - if extract { - G.a.ecb_encrypt(G.Y_0[:]) /* E(K,Y0) */ - for i := 0; i < 16; i++ { - G.Y_0[i] ^= G.stateX[i] - } - for i := 0; i < 16; i++ { - tag[i] = G.Y_0[i] - G.Y_0[i] = 0 - G.stateX[i] = 0 - } - } - G.status = GCM_FINISHED - G.a.End() - return tag -} - -/* AES-GCM Encryption: - K is key, H is header, IV is initialization vector and P is plaintext. - Returns cipthertext and tag (MAC) */ -func AES_GCM_ENCRYPT(K, IV, H, P []byte) ([]byte, []byte) { - g := new(GCM) - lenIV := len(IV) - lenH := len(H) - lenP := len(P) - - g.Init(K, lenIV, IV) - g.Add_header(H, lenH) - C := g.Add_plain(P, lenP) - T := g.Finish(true) - return C, T[:] -} - -/* AES-GCM Deryption: - K is key, H is header, IV is initialization vector and P is plaintext. - Returns cipthertext and tag (MAC) */ -func AES_GCM_DECRYPT(K, IV, H, C []byte) ([]byte, []byte) { - g := new(GCM) - lenIV := len(IV) - lenH := len(H) - lenC := len(C) - - g.Init(K, lenIV, IV) - g.Add_header(H, lenH) - P := g.Add_cipher(C, lenC) - T := g.Finish(true) - return P, T[:] -} - -/* -func hex2bytes(s string) []byte { - lgh:=len(s) - data:=make([]byte,lgh/2) - - for i:=0;i<lgh;i+=2 { - a,_ := strconv.ParseInt(s[i:i+2],16,32) - data[i/2]=byte(a) - } - return data -} - -func main() { - - KT:="feffe9928665731c6d6a8f9467308308" - MT:="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39" - HT:="feedfacedeadbeeffeedfacedeadbeefabaddad2" - - NT:="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b"; -// Tag should be 619cc5aefffe0bfa462af43c1699d050 - - g:=new(GCM) - - M:=hex2bytes(MT) - H:=hex2bytes(HT) - N:=hex2bytes(NT) - K:=hex2bytes(KT) - - lenM:=len(M) - lenH:=len(H) - //lenK:=len(K) - lenIV:=len(N) - - fmt.Printf("Plaintext=\n"); - for i:=0;i<lenM;i++ {fmt.Printf("%02x",M[i])} - fmt.Printf("\n") - - g.Init(K,lenIV,N) - g.Add_header(H,lenH) - C:=g.Add_plain(M,lenM) - T:=g.Finish(true) - - fmt.Printf("Ciphertext=\n") - for i:=0;i<lenM;i++ {fmt.Printf("%02x",C[i])} - fmt.Printf("\n") - - fmt.Printf("Tag=\n") - for i:=0;i<16;i++ {fmt.Printf("%02x",T[i])} - fmt.Printf("\n") - - g.Init(K,lenIV,N) - g.Add_header(H,lenH) - P:=g.Add_cipher(C,lenM) - T=g.Finish(true) - - fmt.Printf("Plaintext=\n"); - for i:=0;i<lenM;i++ {fmt.Printf("%02x",P[i])} - fmt.Printf("\n") - - fmt.Printf("Tag=\n"); - for i:=0;i<16;i++ {fmt.Printf("%02x",T[i])} - fmt.Printf("\n") -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/HASH.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/HASH.go b/go/amcl-go/HASH.go deleted file mode 100644 index c31f51a..0000000 --- a/go/amcl-go/HASH.go +++ /dev/null @@ -1,215 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-256) - * - * Generates a 256 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -package amcl - -//import "fmt" - -const hash_H0 uint32 = 0x6A09E667 -const hash_H1 uint32 = 0xBB67AE85 -const hash_H2 uint32 = 0x3C6EF372 -const hash_H3 uint32 = 0xA54FF53A -const hash_H4 uint32 = 0x510E527F -const hash_H5 uint32 = 0x9B05688C -const hash_H6 uint32 = 0x1F83D9AB -const hash_H7 uint32 = 0x5BE0CD19 - -var hash_K = [...]uint32{ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2} - -type HASH struct { - length [2]uint32 - h [8]uint32 - w [64]uint32 -} - -/* functions */ -func hash_S(n uint32, x uint32) uint32 { - return (((x) >> n) | ((x) << (32 - n))) -} - -func hash_R(n uint32, x uint32) uint32 { - return ((x) >> n) -} - -func hash_Ch(x, y, z uint32) uint32 { - return ((x & y) ^ (^(x) & z)) -} - -func hash_Maj(x, y, z uint32) uint32 { - return ((x & y) ^ (x & z) ^ (y & z)) -} - -func hash_Sig0(x uint32) uint32 { - return (hash_S(2, x) ^ hash_S(13, x) ^ hash_S(22, x)) -} - -func hash_Sig1(x uint32) uint32 { - return (hash_S(6, x) ^ hash_S(11, x) ^ hash_S(25, x)) -} - -func hash_theta0(x uint32) uint32 { - return (hash_S(7, x) ^ hash_S(18, x) ^ hash_R(3, x)) -} - -func hash_theta1(x uint32) uint32 { - return (hash_S(17, x) ^ hash_S(19, x) ^ hash_R(10, x)) -} - -func (H *HASH) transform() { /* basic transformation step */ - for j := 16; j < 64; j++ { - H.w[j] = hash_theta1(H.w[j-2]) + H.w[j-7] + hash_theta0(H.w[j-15]) + H.w[j-16] - } - a := H.h[0] - b := H.h[1] - c := H.h[2] - d := H.h[3] - e := H.h[4] - f := H.h[5] - g := H.h[6] - hh := H.h[7] - for j := 0; j < 64; j++ { /* 64 times - mush it up */ - t1 := hh + hash_Sig1(e) + hash_Ch(e, f, g) + hash_K[j] + H.w[j] - t2 := hash_Sig0(a) + hash_Maj(a, b, c) - hh = g - g = f - f = e - e = d + t1 - d = c - c = b - b = a - a = t1 + t2 - } - H.h[0] += a - H.h[1] += b - H.h[2] += c - H.h[3] += d - H.h[4] += e - H.h[5] += f - H.h[6] += g - H.h[7] += hh -} - -/* Initialise Hash function */ -func (H *HASH) Init() { /* initialise */ - for i := 0; i < 64; i++ { - H.w[i] = 0 - } - H.length[0] = 0 - H.length[1] = 0 - H.h[0] = hash_H0 - H.h[1] = hash_H1 - H.h[2] = hash_H2 - H.h[3] = hash_H3 - H.h[4] = hash_H4 - H.h[5] = hash_H5 - H.h[6] = hash_H6 - H.h[7] = hash_H7 -} - -func NewHASH() *HASH { - H := new(HASH) - H.Init() - return H -} - -/* process a single byte */ -func (H *HASH) Process(byt byte) { /* process the next message byte */ - cnt := (H.length[0] / 32) % 16 - - H.w[cnt] <<= 8 - H.w[cnt] |= uint32(byt & 0xFF) - H.length[0] += 8 - if H.length[0] == 0 { - H.length[1]++ - H.length[0] = 0 - } - if (H.length[0] % 512) == 0 { - H.transform() - } -} - -/* process an array of bytes */ -func (H *HASH) Process_array(b []byte) { - for i := 0; i < len(b); i++ { - H.Process((b[i])) - } -} - -/* process a 32-bit integer */ -func (H *HASH) Process_num(n int32) { - H.Process(byte((n >> 24) & 0xff)) - H.Process(byte((n >> 16) & 0xff)) - H.Process(byte((n >> 8) & 0xff)) - H.Process(byte(n & 0xff)) -} - -/* Generate 32-byte Hash */ -func (H *HASH) Hash() [32]byte { /* pad message and finish - supply digest */ - var digest [32]byte - len0 := H.length[0] - len1 := H.length[1] - H.Process(0x80) - for (H.length[0] % 512) != 448 { - H.Process(0) - } - H.w[14] = len1 - H.w[15] = len0 - H.transform() - for i := 0; i < 32; i++ { /* convert to bytes */ - digest[i] = byte((H.h[i/4] >> uint(8*(3-i%4))) & 0xff) - } - H.Init() - return digest -} - -/* test program: should produce digest */ - -//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1 -/* -func main() { - - test := []byte("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") - sh:=NewHASH() - - for i:=0;i<len(test);i++ { - sh.Process(test[i]) - } - - digest:=sh.Hash() - for i:=0;i<32;i++ {fmt.Printf("%02x",digest[i])} - -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/MPIN.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/MPIN.go b/go/amcl-go/MPIN.go deleted file mode 100644 index 42a2443..0000000 --- a/go/amcl-go/MPIN.go +++ /dev/null @@ -1,807 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* MPIN API Functions */ - -package amcl - -import "time" - -import "fmt" - -/* Configure mode of operation */ - -const PERMITS bool = true -const PINERROR bool = true -const FULL bool = true -const SINGLE_PASS bool = false - -const MPIN_EFS int = int(MODBYTES) -const MPIN_EGS int = int(MODBYTES) -const MPIN_PAS int = 16 -const MPIN_BAD_PARAMS int = -11 -const MPIN_INVALID_POINT int = -14 -const MPIN_WRONG_ORDER int = -18 -const MPIN_BAD_PIN int = -19 - -/* Configure your PIN here */ - -const MPIN_MAXPIN int32 = 10000 /* PIN less than this */ -const MPIN_PBLEN int32 = 14 /* Number of bits in PIN */ -const MPIN_TS int = 10 /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */ -const MPIN_TRAP int = 200 /* 200 for 4 digit PIN, 2000 for 6-digit PIN - approx 2*sqrt(MAXPIN) */ - -/* Hash number (optional) and string to point on curve */ - -func Hashit(n int32, ID []byte) []byte { - H := NewHASH() - if n != 0 { - H.Process_num(n) - } - H.Process_array(ID) - h := H.Hash() - return h[:] -} - -func mapit(h []byte) *ECP { - q := NewBIGints(Modulus) - x := fromBytes(h[:]) - x.mod(q) - var P *ECP - for true { - P = NewECPbigint(x, 0) - if !P.is_infinity() { - break - } - x.inc(1) - x.norm() - } - return P -} - -/* needed for SOK */ -func mapit2(h []byte) *ECP2 { - q := NewBIGints(Modulus) - x := fromBytes(h[:]) - one := NewBIGint(1) - var X *FP2 - var Q, T, K *ECP2 - x.mod(q) - for true { - X = NewFP2bigs(one, x) - Q = NewECP2fp2(X) - if !Q.is_infinity() { - break - } - x.inc(1) - x.norm() - } - /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */ - Fra := NewBIGints(CURVE_Fra) - Frb := NewBIGints(CURVE_Frb) - X = NewFP2bigs(Fra, Frb) - x = NewBIGints(CURVE_Bnx) - - T = NewECP2() - T.copy(Q) - T.mul(x) - T.neg() - K = NewECP2() - K.copy(T) - K.dbl() - K.add(T) - K.affine() - - K.frob(X) - Q.frob(X) - Q.frob(X) - Q.frob(X) - Q.add(T) - Q.add(K) - T.frob(X) - T.frob(X) - Q.add(T) - Q.affine() - return Q -} - -/* return time in slots since epoch */ -func MPIN_today() int { - now := time.Now() - return int(now.Unix()) / (60 * 1440) -} - -/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */ -/* maps a random u to a point on the curve */ -func emap(u *BIG, cb int) *ECP { - var P *ECP - x := NewBIGcopy(u) - p := NewBIGints(Modulus) - x.mod(p) - for true { - P = NewECPbigint(x, cb) - if !P.is_infinity() { - break - } - x.inc(1) - x.norm() - } - return P -} - -/* returns u derived from P. Random value in range 1 to return value should then be added to u */ -func unmap(u *BIG, P *ECP) int { - s := P.getS() - var R *ECP - r := 0 - x := P.getX() - u.copy(x) - for true { - u.dec(1) - u.norm() - r++ - R = NewECPbigint(u, s) - if !R.is_infinity() { - break - } - } - return r -} - -func MPIN_HASH_ID(ID []byte) []byte { - return Hashit(0, ID) -} - -/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */ -/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */ -/* Note that u and v are indistinguisible from random strings */ -func MPIN_ENCODING(rng *RAND, E []byte) int { - var T [MPIN_EFS]byte - - for i := 0; i < MPIN_EFS; i++ { - T[i] = E[i+1] - } - u := fromBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - T[i] = E[i+MPIN_EFS+1] - } - v := fromBytes(T[:]) - - P := NewECPbigs(u, v) - if P.is_infinity() { - return MPIN_INVALID_POINT - } - - p := NewBIGints(Modulus) - u = randomnum(p, rng) - - su := int(rng.GetByte()) - su %= 2 - - W := emap(u, su) - P.sub(W) - sv := P.getS() - rn := unmap(v, P) - m := int(rng.GetByte()) - m %= rn - v.inc(m + 1) - E[0] = byte(su + 2*sv) - u.toBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - E[i+1] = T[i] - } - v.toBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - E[i+MPIN_EFS+1] = T[i] - } - - return 0 -} - -func MPIN_DECODING(D []byte) int { - var T [MPIN_EFS]byte - - if (D[0] & 0x04) != 0 { - return MPIN_INVALID_POINT - } - - for i := 0; i < MPIN_EFS; i++ { - T[i] = D[i+1] - } - u := fromBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - T[i] = D[i+MPIN_EFS+1] - } - v := fromBytes(T[:]) - - su := int(D[0] & 1) - sv := int((D[0] >> 1) & 1) - W := emap(u, su) - P := emap(v, sv) - P.add(W) - u = P.getX() - v = P.getY() - D[0] = 0x04 - u.toBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - D[i+1] = T[i] - } - v.toBytes(T[:]) - for i := 0; i < MPIN_EFS; i++ { - D[i+MPIN_EFS+1] = T[i] - } - - return 0 -} - -/* R=R1+R2 in group G1 */ -func MPIN_RECOMBINE_G1(R1 []byte, R2 []byte, R []byte) int { - P := ECP_fromBytes(R1) - Q := ECP_fromBytes(R2) - - if P.is_infinity() || Q.is_infinity() { - return MPIN_INVALID_POINT - } - - P.add(Q) - - P.toBytes(R[:]) - return 0 -} - -/* W=W1+W2 in group G2 */ -func MPIN_RECOMBINE_G2(W1 []byte, W2 []byte, W []byte) int { - P := ECP2_fromBytes(W1) - Q := ECP2_fromBytes(W2) - - if P.is_infinity() || Q.is_infinity() { - return MPIN_INVALID_POINT - } - - P.add(Q) - - P.toBytes(W) - return 0 -} - -/* create random secret S */ -func MPIN_RANDOM_GENERATE(rng *RAND, S []byte) int { - r := NewBIGints(CURVE_Order) - s := randomnum(r, rng) - - s.toBytes(S) - return 0 -} - -/* Extract PIN from TOKEN for identity CID */ -func MPIN_EXTRACT_PIN(CID []byte, pin int, TOKEN []byte) int { - P := ECP_fromBytes(TOKEN) - if P.is_infinity() { - return MPIN_INVALID_POINT - } - h := Hashit(0, CID) - R := mapit(h) - - R = R.pinmul(int32(pin)%MPIN_MAXPIN, MPIN_PBLEN) - P.sub(R) - - P.toBytes(TOKEN) - - return 0 -} - -/* Implement step 2 on client side of MPin protocol */ -func MPIN_CLIENT_2(X []byte, Y []byte, SEC []byte) int { - r := NewBIGints(CURVE_Order) - P := ECP_fromBytes(SEC) - if P.is_infinity() { - return MPIN_INVALID_POINT - } - - px := fromBytes(X) - py := fromBytes(Y) - px.add(py) - px.mod(r) - px.rsub(r) - - G1mul(P, px).toBytes(SEC) - return 0 -} - -/* Implement step 1 on client side of MPin protocol */ -func MPIN_CLIENT_1(date int, CLIENT_ID []byte, rng *RAND, X []byte, pin int, TOKEN []byte, SEC []byte, xID []byte, xCID []byte, PERMIT []byte) int { - r := NewBIGints(CURVE_Order) - - var x *BIG - if rng != nil { - x = randomnum(r, rng) - x.toBytes(X) - } else { - x = fromBytes(X) - } - - h := Hashit(0, CLIENT_ID) - P := mapit(h) - - T := ECP_fromBytes(TOKEN) - if T.is_infinity() { - return MPIN_INVALID_POINT - } - - W := P.pinmul(int32(pin)%MPIN_MAXPIN, MPIN_PBLEN) - T.add(W) - if date != 0 { - W = ECP_fromBytes(PERMIT) - if W.is_infinity() { - return MPIN_INVALID_POINT - } - T.add(W) - h = Hashit(int32(date), h) - W = mapit(h) - if xID != nil { - P = G1mul(P, x) - P.toBytes(xID) - W = G1mul(W, x) - P.add(W) - } else { - P.add(W) - P = G1mul(P, x) - } - if xCID != nil { - P.toBytes(xCID) - } - } else { - if xID != nil { - P = G1mul(P, x) - P.toBytes(xID) - } - } - - T.toBytes(SEC) - return 0 -} - -/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */ -func MPIN_GET_SERVER_SECRET(S []byte, SST []byte) int { - Q := NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa), NewBIGints(CURVE_Pxb)), NewFP2bigs(NewBIGints(CURVE_Pya), NewBIGints(CURVE_Pyb))) - - s := fromBytes(S) - Q = G2mul(Q, s) - Q.toBytes(SST) - return 0 -} - -/* - W=x*H(G); - if RNG == NULL then X is passed in - if RNG != NULL the X is passed out - if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve -*/ -func MPIN_GET_G1_MULTIPLE(rng *RAND, typ int, X []byte, G []byte, W []byte) int { - var x *BIG - r := NewBIGints(CURVE_Order) - if rng != nil { - x = randomnum(r, rng) - x.toBytes(X) - } else { - x = fromBytes(X) - } - var P *ECP - if typ == 0 { - P = ECP_fromBytes(G) - if P.is_infinity() { - return MPIN_INVALID_POINT - } - } else { - P = mapit(G) - } - - G1mul(P, x).toBytes(W) - return 0 -} - -/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */ -/* CID is hashed externally */ -func MPIN_GET_CLIENT_SECRET(S []byte, CID []byte, CST []byte) int { - return MPIN_GET_G1_MULTIPLE(nil, 1, S, CID, CST) -} - -/* Time Permit CTT=S*(date|H(CID)) where S is master secret */ -func MPIN_GET_CLIENT_PERMIT(date int, S []byte, CID []byte, CTT []byte) int { - h := Hashit(int32(date), CID) - P := mapit(h) - - s := fromBytes(S) - G1mul(P, s).toBytes(CTT) - return 0 -} - -/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */ -func MPIN_SERVER_1(date int, CID []byte, HID []byte, HTID []byte) { - h := Hashit(0, CID) - P := mapit(h) - - if date != 0 { - if HID != nil { - P.toBytes(HID) - } - h = Hashit(int32(date), h) - R := mapit(h) - P.add(R) - P.toBytes(HTID) - } else { - P.toBytes(HID) - } -} - -/* Implement step 2 of MPin protocol on server side */ -func MPIN_SERVER_2(date int, HID []byte, HTID []byte, Y []byte, SST []byte, xID []byte, xCID []byte, mSEC []byte, E []byte, F []byte) int { - // q:=NewBIGints(Modulus) - Q := NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa), NewBIGints(CURVE_Pxb)), NewFP2bigs(NewBIGints(CURVE_Pya), NewBIGints(CURVE_Pyb))) - - sQ := ECP2_fromBytes(SST) - if sQ.is_infinity() { - return MPIN_INVALID_POINT - } - - var R *ECP - if date != 0 { - R = ECP_fromBytes(xCID) - } else { - if xID == nil { - return MPIN_BAD_PARAMS - } - R = ECP_fromBytes(xID) - } - if R.is_infinity() { - return MPIN_INVALID_POINT - } - - y := fromBytes(Y) - var P *ECP - if date != 0 { - P = ECP_fromBytes(HTID) - } else { - if HID == nil { - return MPIN_BAD_PARAMS - } - P = ECP_fromBytes(HID) - } - - if P.is_infinity() { - return MPIN_INVALID_POINT - } - - P = G1mul(P, y) - P.add(R) - R = ECP_fromBytes(mSEC) - if R.is_infinity() { - return MPIN_INVALID_POINT - } - - var g *FP12 - // FP12 g1=new FP12(0); - - g = ate2(Q, R, sQ, P) - g = fexp(g) - - if !g.isunity() { - if HID != nil && xID != nil && E != nil && F != nil { - g.toBytes(E) - if date != 0 { - P = ECP_fromBytes(HID) - if P.is_infinity() { - return MPIN_INVALID_POINT - } - R = ECP_fromBytes(xID) - if R.is_infinity() { - return MPIN_INVALID_POINT - } - - P = G1mul(P, y) - P.add(R) - } - g = ate(Q, P) - g = fexp(g) - g.toBytes(F) - } - return MPIN_BAD_PIN - } - - return 0 -} - -/* Pollards kangaroos used to return PIN error */ -func MPIN_KANGAROO(E []byte, F []byte) int { - ge := FP12_fromBytes(E) - gf := FP12_fromBytes(F) - var distance [MPIN_TS]int - t := NewFP12copy(gf) - - var table []*FP12 - var i int - s := 1 - for m := 0; m < MPIN_TS; m++ { - distance[m] = s - table = append(table, NewFP12copy(t)) - s *= 2 - t.usqr() - } - t.one() - dn := 0 - for j := 0; j < MPIN_TRAP; j++ { - i = t.geta().geta().getA().lastbits(8) % MPIN_TS - t.mul(table[i]) - dn += distance[i] - } - gf.copy(t) - gf.conj() - steps := 0 - dm := 0 - res := 0 - for dm-dn < int(MPIN_MAXPIN) { - steps++ - if steps > 4*MPIN_TRAP { - break - } - i = ge.geta().geta().getA().lastbits(8) % MPIN_TS - ge.mul(table[i]) - dm += distance[i] - if ge.equals(t) { - res = dm - dn - break - } - if ge.equals(gf) { - res = dn - dm - break - } - - } - if steps > 4*MPIN_TRAP || dm-dn >= int(MPIN_MAXPIN) { - res = 0 - } // Trap Failed - probable invalid token - return int(res) -} - -/* Functions to support M-Pin Full */ - -func MPIN_PRECOMPUTE(TOKEN []byte, CID []byte, G1 []byte, G2 []byte) int { - var P, T *ECP - var g *FP12 - - T = ECP_fromBytes(TOKEN) - if T.is_infinity() { - return MPIN_INVALID_POINT - } - - P = mapit(CID) - - Q := NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa), NewBIGints(CURVE_Pxb)), NewFP2bigs(NewBIGints(CURVE_Pya), NewBIGints(CURVE_Pyb))) - - g = ate(Q, T) - g = fexp(g) - g.toBytes(G1) - - g = ate(Q, P) - g = fexp(g) - g.toBytes(G2) - - return 0 -} - -/* calculate common key on client side */ -/* wCID = w.(A+AT) */ -func MPIN_CLIENT_KEY(G1 []byte, G2 []byte, pin int, R []byte, X []byte, wCID []byte, CK []byte) int { - H := NewHASH() - var t [MPIN_EFS]byte - - g1 := FP12_fromBytes(G1) - g2 := FP12_fromBytes(G2) - z := fromBytes(R) - x := fromBytes(X) - - W := ECP_fromBytes(wCID) - if W.is_infinity() { - return MPIN_INVALID_POINT - } - - W = G1mul(W, x) - - f := NewFP2bigs(NewBIGints(CURVE_Fra), NewBIGints(CURVE_Frb)) - r := NewBIGints(CURVE_Order) - q := NewBIGints(Modulus) - - m := NewBIGcopy(q) - m.mod(r) - - a := NewBIGcopy(z) - a.mod(m) - - b := NewBIGcopy(z) - b.div(m) - - g2.pinpow(pin, int(MPIN_PBLEN)) - g1.mul(g2) - - c := g1.trace() - g2.copy(g1) - g2.frob(f) - cp := g2.trace() - g1.conj() - g2.mul(g1) - cpm1 := g2.trace() - g2.mul(g1) - cpm2 := g2.trace() - - c = c.xtr_pow2(cp, cpm1, cpm2, a, b) - - c.geta().getA().toBytes(t[:]) - H.Process_array(t[:]) - c.geta().getB().toBytes(t[:]) - H.Process_array(t[:]) - c.getb().getA().toBytes(t[:]) - H.Process_array(t[:]) - c.getb().getB().toBytes(t[:]) - H.Process_array(t[:]) - - W.getX().toBytes(t[:]) - H.Process_array(t[:]) - W.getY().toBytes(t[:]) - H.Process_array(t[:]) - - t = H.Hash() - for i := 0; i < MPIN_PAS; i++ { - CK[i] = t[i] - } - - return 0 -} - -/* calculate common key on server side */ -/* Z=r.A - no time permits involved */ - -func MPIN_SERVER_KEY(Z []byte, SST []byte, W []byte, xID []byte, xCID []byte, SK []byte) int { - H := NewHASH() - var t [MPIN_EFS]byte - - sQ := ECP2_fromBytes(SST) - if sQ.is_infinity() { - return MPIN_INVALID_POINT - } - R := ECP_fromBytes(Z) - if R.is_infinity() { - return MPIN_INVALID_POINT - } - - var U *ECP - if xCID != nil { - U = ECP_fromBytes(xCID) - } else { - U = ECP_fromBytes(xID) - } - if U.is_infinity() { - return MPIN_INVALID_POINT - } - - w := fromBytes(W) - U = G1mul(U, w) - g := ate(sQ, R) - g = fexp(g) - - c := g.trace() - c.geta().getA().toBytes(t[:]) - H.Process_array(t[:]) - c.geta().getB().toBytes(t[:]) - H.Process_array(t[:]) - c.getb().getA().toBytes(t[:]) - H.Process_array(t[:]) - c.getb().getB().toBytes(t[:]) - H.Process_array(t[:]) - - U.getX().toBytes(t[:]) - H.Process_array(t[:]) - U.getY().toBytes(t[:]) - H.Process_array(t[:]) - - t = H.Hash() - for i := 0; i < MPIN_PAS; i++ { - SK[i] = t[i] - } - - return 0 -} - -/* return time since epoch */ -func MPIN_GET_TIME() int { - now := time.Now() - return int(now.Unix()) -} - -/* Generate Y = H(epoch, xCID/xID) */ -func MPIN_GET_Y(TimeValue int, xCID []byte, Y []byte) { - h := Hashit(int32(TimeValue), xCID) - y := fromBytes(h) - q := NewBIGints(CURVE_Order) - y.mod(q) - y.toBytes(Y) -} - -/* One pass MPIN Client */ -func MPIN_CLIENT(date int, CLIENT_ID []byte, RNG *RAND, X []byte, pin int, TOKEN []byte, SEC []byte, xID []byte, xCID []byte, PERMIT []byte, MESSAGE []byte, TimeValue int, Y []byte) int { - rtn := 0 - - var M []byte - if date == 0 { - M = xID - } else { - M = xCID - } - - rtn = MPIN_CLIENT_1(date, CLIENT_ID, RNG, X, pin, TOKEN, SEC, xID, xCID, PERMIT) - if rtn != 0 { - return rtn - } - - if MESSAGE != nil { - M = append(M, MESSAGE...) - } - - MPIN_GET_Y(TimeValue, M, Y) - - rtn = MPIN_CLIENT_2(X, Y, SEC) - if rtn != 0 { - return rtn - } - - return 0 -} - -/* One pass MPIN Server */ -func MPIN_SERVER(date int, HID []byte, HTID []byte, Y []byte, SST []byte, xID []byte, xCID []byte, SEC []byte, E []byte, F []byte, CID []byte, MESSAGE []byte, TimeValue int) int { - rtn := 0 - - var M []byte - if date == 0 { - M = xID - } else { - M = xCID - } - - MPIN_SERVER_1(date, CID, HID, HTID) - - if MESSAGE != nil { - M = append(M, MESSAGE...) - } - - MPIN_GET_Y(TimeValue, M, Y) - - rtn = MPIN_SERVER_2(date, HID, HTID, Y, SST, xID, xCID, SEC, E, F) - if rtn != 0 { - return rtn - } - - return 0 -} - -func MPIN_printBinary(array []byte) { - for i := 0; i < len(array); i++ { - fmt.Printf("%02x", array[i]) - } - fmt.Printf("\n") -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/go/amcl-go/MPIN_test.go ---------------------------------------------------------------------- diff --git a/go/amcl-go/MPIN_test.go b/go/amcl-go/MPIN_test.go deleted file mode 100644 index f489bea..0000000 --- a/go/amcl-go/MPIN_test.go +++ /dev/null @@ -1,898 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -package amcl - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "testing" -) - -func TestGoodPIN(t *testing.T) { - want := 0 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - var MESSAGE []byte - // MESSAGE := []byte("test sign message") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("MPIN GOOD PIN %d != %d", want, got) - } -} - -func TestBadPIN(t *testing.T) { - want := -19 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1235 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - var MESSAGE []byte - // MESSAGE := []byte("test sign message") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestBadPIN %d != %d", want, got) - } -} - -func TestBadToken(t *testing.T) { - want := -19 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - var MESSAGE []byte - // MESSAGE := []byte("test sign message") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - // Send UT as V to model bad token - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], UT[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestBadToken %d != %d", want, got) - } -} - -func TestRandom(t *testing.T) { - want := 0 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seed := make([]byte, 16) - rand.Read(seed) - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - var MESSAGE []byte - // MESSAGE := []byte("test sign message") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestRandom %d != %d", want, got) - } -} - -func TestGoodSignature(t *testing.T) { - want := 0 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Message to sign - MESSAGE := []byte("test message to sign") - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestGoodSignature %d != %d", want, got) - } -} - -func TestSignatureExpired(t *testing.T) { - want := -19 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - MESSAGE := []byte("test message to sign") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - timeValue += 10 - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestSignatureExpired %d != %d", want, got) - } -} - -func TestBadSignature(t *testing.T) { - want := -19 - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - MESSAGE := []byte("test message to sign") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - MESSAGE[0] = 00 - got := MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - if got != want { - t.Errorf("TestBadSignature %d != %d", want, got) - } -} - -func TestMPINFull(t *testing.T) { - want := "0afc948b03b2733a0663571f86411a07" - // Assign the End-User an ID - IDstr := "[email protected]" - ID := []byte(IDstr) - - // Epoch time in days - date := 16660 - - // Epoch time in seconds - timeValue := 1439465203 - - // PIN variable to create token - PIN1 := 1234 - // PIN variable to authenticate - PIN2 := 1234 - - // Seed value for Random Number Generator (RNG) - seedHex := "9e8b4178790cd57a5761c4a6f164ba72" - seed, err := hex.DecodeString(seedHex) - if err != nil { - fmt.Println("Error decoding seed value") - return - } - rng := NewRAND() - rng.Seed(len(seed), seed) - - // Message to sign - var MESSAGE []byte - // MESSAGE := []byte("test sign message") - - const EGS = MPIN_EGS - const EFS = MPIN_EFS - const G1S = 2*EFS + 1 /* Group 1 Size */ - const G2S = 4 * EFS /* Group 2 Size */ - const EAS = MPIN_PAS - - var MS1 [EGS]byte - var SS1 [G2S]byte - var CS1 [G1S]byte - var TP1 [G1S]byte - var MS2 [EGS]byte - var SS2 [G2S]byte - var CS2 [G1S]byte - var TP2 [G1S]byte - var SS [G2S]byte - var TP [G1S]byte - var TOKEN [G1S]byte - var SEC [G1S]byte - var U [G1S]byte - var UT [G1S]byte - var X [EGS]byte - var Y [EGS]byte - var E [12 * EFS]byte - var F [12 * EFS]byte - var HID [G1S]byte - var HTID [G1S]byte - - var G1 [12 * EFS]byte - var G2 [12 * EFS]byte - var R [EGS]byte - var Z [G1S]byte - var W [EGS]byte - var T [G1S]byte - var AES_KEY_CLIENT [EAS]byte - var AES_KEY_SERVER [EAS]byte - - // Generate Master Secret Share 1 - MPIN_RANDOM_GENERATE(rng, MS1[:]) - - // Generate Master Secret Share 2 - MPIN_RANDOM_GENERATE(rng, MS2[:]) - - // Either Client or TA calculates Hash(ID) - HCID := MPIN_HASH_ID(ID) - - // Generate server secret share 1 - MPIN_GET_SERVER_SECRET(MS1[:], SS1[:]) - - // Generate server secret share 2 - MPIN_GET_SERVER_SECRET(MS2[:], SS2[:]) - - // Combine server secret shares - MPIN_RECOMBINE_G2(SS1[:], SS2[:], SS[:]) - - // Generate client secret share 1 - MPIN_GET_CLIENT_SECRET(MS1[:], HCID, CS1[:]) - - // Generate client secret share 2 - MPIN_GET_CLIENT_SECRET(MS2[:], HCID, CS2[:]) - - // Combine client secret shares : TOKEN is the full client secret - MPIN_RECOMBINE_G1(CS1[:], CS2[:], TOKEN[:]) - - // Generate time permit share 1 - MPIN_GET_CLIENT_PERMIT(date, MS1[:], HCID, TP1[:]) - - // Generate time permit share 2 - MPIN_GET_CLIENT_PERMIT(date, MS2[:], HCID, TP2[:]) - - // Combine time permit shares - MPIN_RECOMBINE_G1(TP1[:], TP2[:], TP[:]) - - // Create token - MPIN_EXTRACT_PIN(ID, PIN1, TOKEN[:]) - - // precomputation - MPIN_PRECOMPUTE(TOKEN[:], HCID, G1[:], G2[:]) - - // Authenticate - MPIN_CLIENT(date, ID, rng, X[:], PIN2, TOKEN[:], SEC[:], U[:], UT[:], TP[:], MESSAGE, timeValue, Y[:]) - - // Send Z=r.ID to Server - MPIN_GET_G1_MULTIPLE(rng, 1, R[:], HCID, Z[:]) - - MPIN_SERVER(date, HID[:], HTID[:], Y[:], SS[:], U[:], UT[:], SEC[:], E[:], F[:], ID, MESSAGE, timeValue) - - // send T=w.ID to client - MPIN_GET_G1_MULTIPLE(rng, 0, W[:], HTID[:], T[:]) - - MPIN_SERVER_KEY(Z[:], SS[:], W[:], U[:], UT[:], AES_KEY_SERVER[:]) - got := hex.EncodeToString(AES_KEY_SERVER[:]) - if got != want { - t.Errorf("TestMPINFull %s != %s", want, got) - } - - MPIN_CLIENT_KEY(G1[:], G2[:], PIN2, R[:], X[:], T[:], AES_KEY_CLIENT[:]) - got = hex.EncodeToString(AES_KEY_CLIENT[:]) - if got != want { - t.Errorf("TestMPINFull %s != %s", want, got) - } -}
