http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/fp12.swift ---------------------------------------------------------------------- diff --git a/version22/swift/fp12.swift b/version22/swift/fp12.swift deleted file mode 100644 index 8743677..0000000 --- a/version22/swift/fp12.swift +++ /dev/null @@ -1,584 +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. -*/ - -// -// fp12.swift -// -// Created by Michael Scott on 07/07/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -/* AMCL Fp^12 functions */ -/* FP12 elements are of the form a+i.b+i^2.c */ - -final class FP12 -{ - private final var a:FP4 - private final var b:FP4 - private final var c:FP4 - - /* reduce all components of this mod Modulus */ - func reduce() - { - a.reduce() - b.reduce() - c.reduce() - } - /* normalise all components of this */ - func norm() - { - a.norm(); - b.norm(); - c.norm(); - } - /* Constructors */ - init(_ d:FP4) - { - a=FP4(d) - b=FP4(0) - c=FP4(0) - } - - init(_ d:Int) - { - a=FP4(d) - b=FP4(0) - c=FP4(0) - } - - init(_ d:FP4,_ e:FP4,_ f:FP4) - { - a=FP4(d) - b=FP4(e) - c=FP4(f) - } - - init(_ x:FP12) - { - a=FP4(x.a) - b=FP4(x.b) - c=FP4(x.c) - } - /* test x==0 ? */ - func iszilch() -> Bool - { - reduce(); - return a.iszilch() && b.iszilch() && c.iszilch() - } - /* test x==1 ? */ - func isunity() -> Bool - { - let one=FP4(1) - return a.equals(one) && b.iszilch() && c.iszilch() - } - /* return 1 if x==y, else 0 */ - func equals(_ x:FP12) -> Bool - { - return a.equals(x.a) && b.equals(x.b) && c.equals(x.c) - } - /* extract a from self */ - func geta() -> FP4 - { - return a - } - /* extract b */ - func getb() -> FP4 - { - return b - } - /* extract c */ - func getc() -> FP4 - { - return c - } - /* copy self=x */ - func copy(_ x:FP12) - { - a.copy(x.a) - b.copy(x.b) - c.copy(x.c) - } - /* set self=1 */ - func one() - { - a.one() - b.zero() - c.zero() - } - /* self=conj(self) */ - func conj() - { - a.conj() - b.nconj() - c.conj() - } - /* Granger-Scott Unitary Squaring */ - func usqr() - { - let A=FP4(a) - let B=FP4(c) - let C=FP4(b) - let D=FP4(0) - - a.sqr() - D.copy(a); D.add(a) - a.add(D) - - a.norm() - A.nconj() - - A.add(A) - 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() - - b.conj() - b.add(b) - c.nconj() - - c.add(c) - b.add(B) - c.add(C) - reduce() - - } - /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ - func sqr() - { - let A=FP4(a) - let B=FP4(b) - let C=FP4(c) - let D=FP4(a) - - A.sqr() - B.mul(c) - B.add(B) - C.sqr() - D.mul(b) - D.add(D) - - c.add(a) - c.add(b) - c.sqr() - - a.copy(A) - - A.add(B) - A.norm() - A.add(C) - A.add(D) - A.norm() - - A.neg() - B.times_i() - C.times_i() - - a.add(B) - - b.copy(C); b.add(D) - c.add(A) - - norm() - } - - /* FP12 full multiplication this=this*y */ - func mul(_ y:FP12) - { - let z0=FP4(a) - let z1=FP4(0) - let z2=FP4(b) - let z3=FP4(0) - let t0=FP4(a) - let t1=FP4(y.a) - - z0.mul(y.a) - z2.mul(y.b) - - t0.add(b) - t1.add(y.b) - - z1.copy(t0); z1.mul(t1) - t0.copy(b); t0.add(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() - b.copy(z1); b.add(t1) - - z3.add(t1) - z2.add(t0) - - t0.copy(a); t0.add(c) - t1.copy(y.a); t1.add(y.c) - t0.mul(t1) - z2.add(t0) - - t0.copy(c); t0.mul(y.c) - t1.copy(t0); t1.neg() - - z2.norm() - z3.norm() - b.norm() - - c.copy(z2); c.add(t1) - z3.add(t1) - t0.times_i() - b.add(t0) - - z3.times_i() - a.copy(z0); a.add(z3) - - norm() - } - - /* Special case of multiplication arises from special form of ATE pairing line function */ - func smul(_ y:FP12) - { - let z0=FP4(a) - let z2=FP4(b) - let z3=FP4(b) - let t0=FP4(0) - let t1=FP4(y.a) - - z0.mul(y.a) - z2.pmul(y.b.real()) - b.add(a) - t1.real().add(y.b.real()) - - b.mul(t1) - z3.add(c) - z3.pmul(y.b.real()) - - t0.copy(z0); t0.neg() - t1.copy(z2); t1.neg() - - b.add(t0) - b.norm() - - b.add(t1) - z3.add(t1) - z2.add(t0) - - t0.copy(a); t0.add(c) - t0.mul(y.a) - c.copy(z2); c.add(t0) - - z3.times_i() - a.copy(z0); a.add(z3) - - norm() - } - /* self=1/self */ - func inverse() - { - let f0=FP4(a) - let f1=FP4(b) - let f2=FP4(a) - let f3=FP4(0) - - norm() - f0.sqr() - f1.mul(c) - f1.times_i() - f0.sub(f1) - - f1.copy(c); f1.sqr() - f1.times_i() - f2.mul(b) - f1.sub(f2) - - f2.copy(b); f2.sqr() - f3.copy(a); f3.mul(c) - f2.sub(f3) - - f3.copy(b); f3.mul(f2) - f3.times_i() - a.mul(f0) - f3.add(a) - c.mul(f1) - c.times_i() - - f3.add(c) - f3.inverse() - a.copy(f0); a.mul(f3) - b.copy(f1); b.mul(f3) - c.copy(f2); c.mul(f3) - } - - /* self=self^p using Frobenius */ - func frob(_ f:FP2) - { - let f2=FP2(f) - let f3=FP2(f) - - f2.sqr() - f3.mul(f2) - - a.frob(f3) - b.frob(f3) - c.frob(f3) - - b.pmul(f) - c.pmul(f2) - } - - /* trace function */ - func trace() -> FP4 - { - let t=FP4(0) - t.copy(a) - t.imul(3) - t.reduce() - return t - } - /* convert from byte array to FP12 */ - static func fromBytes(_ w:[UInt8]) -> FP12 - { - let RM=Int(ROM.MODBYTES) - var t=[UInt8](repeating: 0,count: RM) - - for i in 0 ..< RM {t[i]=w[i]} - var a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+RM]} - var b=BIG.fromBytes(t) - var c=FP2(a,b) - - for i in 0 ..< RM {t[i]=w[i+2*RM]} - a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+3*RM]} - b=BIG.fromBytes(t) - var d=FP2(a,b) - - let e=FP4(c,d) - - for i in 0 ..< RM {t[i]=w[i+4*RM]} - a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+5*RM]} - b=BIG.fromBytes(t) - c=FP2(a,b) - - for i in 0 ..< RM {t[i]=w[i+6*RM]} - a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+7*RM]} - b=BIG.fromBytes(t) - d=FP2(a,b) - - let f=FP4(c,d) - - - for i in 0 ..< RM {t[i]=w[i+8*RM]} - a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+9*RM]} - b=BIG.fromBytes(t) - c=FP2(a,b) - - for i in 0 ..< RM {t[i]=w[i+10*RM]} - a=BIG.fromBytes(t) - for i in 0 ..< RM {t[i]=w[i+11*RM]} - b=BIG.fromBytes(t); - d=FP2(a,b) - - let g=FP4(c,d) - - return FP12(e,f,g) - } - - /* convert this to byte array */ - func toBytes(_ w:inout [UInt8]) - { - let RM=Int(ROM.MODBYTES) - var t=[UInt8](repeating: 0,count: RM) - - a.geta().getA().toBytes(&t) - for i in 0 ..< RM {w[i]=t[i]} - a.geta().getB().toBytes(&t) - for i in 0 ..< RM {w[i+RM]=t[i]} - a.getb().getA().toBytes(&t) - for i in 0 ..< RM {w[i+2*RM]=t[i]} - a.getb().getB().toBytes(&t) - for i in 0 ..< RM {w[i+3*RM]=t[i]} - - b.geta().getA().toBytes(&t) - for i in 0 ..< RM {w[i+4*RM]=t[i]} - b.geta().getB().toBytes(&t); - for i in 0 ..< RM {w[i+5*RM]=t[i]} - b.getb().getA().toBytes(&t) - for i in 0 ..< RM {w[i+6*RM]=t[i]} - b.getb().getB().toBytes(&t) - for i in 0 ..< RM {w[i+7*RM]=t[i]} - - c.geta().getA().toBytes(&t) - for i in 0 ..< RM {w[i+8*RM]=t[i]} - c.geta().getB().toBytes(&t) - for i in 0 ..< RM {w[i+9*RM]=t[i]} - c.getb().getA().toBytes(&t) - for i in 0 ..< RM {w[i+10*RM]=t[i]} - c.getb().getB().toBytes(&t) - for i in 0 ..< RM {w[i+11*RM]=t[i]} - } - /* convert to hex string */ - func toString() -> String - { - return ("["+a.toString()+","+b.toString()+","+c.toString()+"]") - } - - /* self=self^e */ - /* Note this is simple square and multiply, so not side-channel safe */ - func pow(_ e:BIG) -> FP12 - { - norm() - e.norm() - let w=FP12(self) - let z=BIG(e) - let r=FP12(1) - - while (true) - { - let 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 pinpow(_ e:Int32,_ bts:Int32) - { - var R=[FP12]() - R.append(FP12(1)); - R.append(FP12(self)); - - //for var i=bts-1;i>=0;i-- - for i in (0...bts-1).reversed() - { - let b=Int((e>>i)&1) - R[1-b].mul(R[b]) - R[b].usqr() - } - copy(R[0]); - } - - /* p=q0^u0.q1^u1.q2^u2.q3^u3 */ - /* Timing attack secure, but not cache attack secure */ - - static func pow4(_ q:[FP12],_ u:[BIG]) -> FP12 - { - var a=[Int32](repeating: 0,count: 4) - var g=[FP12](); - - for _ in 0 ..< 8 {g.append(FP12(0))} - var s=[FP12](); - for _ in 0 ..< 2 {s.append(FP12(0))} - - let c=FP12(1) - let p=FP12(0) - - var t=[BIG]() - for i in 0 ..< 4 - {t.append(BIG(u[i]))} - - let mt=BIG(0); - var w=[Int8](repeating: 0,count: ROM.NLEN*Int(ROM.BASEBITS)+1) - - g[0].copy(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]) - g[1].copy(g[0]) - g[2].copy(g[0]) - g[3].copy(g[0]) - g[4].copy(q[0]); g[4].mul(q[1]) - g[5].copy(g[4]) - g[6].copy(g[4]) - g[7].copy(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 in 0 ..< 4 - { - if t[i].parity()==0 - { - t[i].inc(1); t[i].norm() - c.mul(q[i]) - } - mt.add(t[i]); mt.norm() - } - c.conj(); - let nb=1+mt.nbits(); - - /* convert exponent to signed 1-bit window */ - for j in 0 ..< nb - { - for i in 0 ..< 4 - { - a[i]=Int32(t[i].lastbits(2)-2) - t[i].dec(Int(a[i])); - t[i].norm() - t[i].fshr(1) - } - w[j]=Int8(8*a[0]+4*a[1]+2*a[2]+a[3]) - } - w[nb]=Int8(8*t[0].lastbits(2)+4*t[1].lastbits(2)) - w[nb]+=Int8(2*t[2].lastbits(2)+t[3].lastbits(2)) - p.copy(g[Int(w[nb]-1)/2]) - - //for var i=nb-1;i>=0;i-- - for i in (0...nb-1).reversed() - { - let m=w[i]>>7 - let j=(w[i]^m)-m /* j=abs(w[i]) */ - let k=Int((j-1)/2) - s[0].copy(g[k]); s[1].copy(g[k]); s[1].conj() - p.usqr() - p.mul(s[Int(m&1)]) - } - p.mul(c) /* apply correction */ - p.reduce() - return p - } - - - - - -}
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/fp2.swift ---------------------------------------------------------------------- diff --git a/version22/swift/fp2.swift b/version22/swift/fp2.swift deleted file mode 100644 index cdc1711..0000000 --- a/version22/swift/fp2.swift +++ /dev/null @@ -1,329 +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. -*/ - -// -// fp2.swift -// -// Created by Michael Scott on 07/07/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -/* Finite Field arithmetic Fp^2 functions */ - -/* FP2 elements are of the form a+ib, where i is sqrt(-1) */ - - -final class FP2 -{ - private var a:FP - private var b:FP - - /* Constructors */ - init(_ c: Int) - { - a=FP(c) - b=FP(0) - } - - init(_ x:FP2) - { - a=FP(x.a) - b=FP(x.b) - } - - init(_ c:FP,_ d:FP) - { - a=FP(c) - b=FP(d) - } - - init(_ c:BIG,_ d:BIG) - { - a=FP(c) - b=FP(d) - } - - init(_ c:FP) - { - a=FP(c) - b=FP(0) - } - - init(_ c:BIG) - { - a=FP(c) - b=FP(0) - } - - /* test this=0 ? */ - func iszilch() -> Bool - { - reduce() - return (a.iszilch() && b.iszilch()) - } - - func cmove(_ g:FP2,_ d:Int) - { - a.cmove(g.a,d) - b.cmove(g.b,d) - } - - /* test this=1 ? */ - func isunity() -> Bool - { - let one=FP(1) - return (a.equals(one) && b.iszilch()) - } - - /* test this=x */ - func equals(_ x:FP2) -> Bool - { - return (a.equals(x.a) && b.equals(x.b)); - } - - - /* reduce components mod Modulus */ - func reduce() - { - a.reduce() - b.reduce() - } - - /* normalise components of w */ - func norm() - { - a.norm() - b.norm() - } - - /* extract a */ - func getA() -> BIG - { - return a.redc() - } - - /* extract b */ - func getB() -> BIG - { - return b.redc() - } - - /* copy self=x */ - func copy(_ x:FP2) - { - a.copy(x.a) - b.copy(x.b) - } - - /* set self=0 */ - func zero() - { - a.zero() - b.zero() - } - - /* set self=1 */ - func one() - { - a.one() - b.zero() - } - - /* negate self mod Modulus */ - func neg() - { - norm(); - let m=FP(a) - let t=FP(0) - - m.add(b) - m.neg() - m.norm() - t.copy(m); t.add(b) - b.copy(m) - b.add(a) - a.copy(t) - } - - /* set to a-ib */ - func conj() - { - b.neg() - } - - /* self+=a */ - func add(_ x:FP2) - { - a.add(x.a) - b.add(x.b) - } - - /* self-=a */ - func sub(_ x:FP2) - { - let m=FP2(x) - m.neg() - add(m) - } - - /* self*=s, where s is an FP */ - func pmul(_ s:FP) - { - a.mul(s) - b.mul(s) - } - - /* self*=i, where i is an int */ - func imul(_ c:Int) - { - a.imul(c); - b.imul(c); - } - - /* self*=self */ - func sqr() - { - norm(); - - let w1=FP(a) - let w3=FP(a) - let mb=FP(b) - w3.mul(b) - w1.add(b) - mb.neg() - a.add(mb) - a.mul(w1) - b.copy(w3); b.add(w3) - norm() - } - /* self*=y */ - func mul(_ y:FP2) - { - norm(); /* This is needed here as {a,b} is not normed before additions */ - - let w1=FP(a) - let w2=FP(b) - let w5=FP(a) - let mw=FP(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(b) // w5=a+b - b.copy(y.a); b.add(y.b) // b=y.a+y.b - - b.mul(w5) - mw.copy(w1); mw.add(w2); mw.neg() - - b.add(mw); mw.add(w1) - a.copy(w1); a.add(mw) - - 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 sqrt() -> Bool - { - if iszilch() {return true} - var w1=FP(b) - var w2=FP(a) - w1.sqr(); w2.sqr(); w1.add(w2) - if w1.jacobi() != 1 { zero(); return false; } - w1=w1.sqrt() - w2.copy(a); w2.add(w1); w2.div2() - if w2.jacobi() != 1 - { - w2.copy(a); w2.sub(w1); w2.div2() - if w2.jacobi() != 1 { zero(); return false } - } - w2=w2.sqrt() - a.copy(w2) - w2.add(w2) - w2.inverse() - b.mul(w2) - return true - } - /* output to hex string */ - func toString() -> String - { - return ("["+a.toString()+","+b.toString()+"]") - } - - func toRawString() -> String - { - return ("["+a.toRawString()+","+b.toRawString()+"]") - } - - /* self=1/self */ - func inverse() - { - norm(); - let w1=FP(a) - let w2=FP(b) - - w1.sqr() - w2.sqr() - w1.add(w2) - w1.inverse() - a.mul(w1) - w1.neg() - b.mul(w1) - } - - /* self/=2 */ - func div2() - { - a.div2(); - b.div2(); - } - - /* self*=sqrt(-1) */ - func times_i() - { - let z=FP(a) - a.copy(b); a.neg() - b.copy(z) - } - - /* w*=(1+sqrt(-1)) */ - /* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */ - func mul_ip() - { - norm(); - let t=FP2(self) - let z=FP(a) - a.copy(b) - a.neg() - b.copy(z) - add(t) - norm() - } - /* w/=(1+sqrt(-1)) */ - func div_ip() - { - let t=FP2(0) - norm() - t.a.copy(a); t.a.add(b) - t.b.copy(b); t.b.sub(a) - copy(t) - div2() - } - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/fp4.swift ---------------------------------------------------------------------- diff --git a/version22/swift/fp4.swift b/version22/swift/fp4.swift deleted file mode 100644 index 3cba394..0000000 --- a/version22/swift/fp4.swift +++ /dev/null @@ -1,517 +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. -*/ - -// -// fp4.swift -// -// Created by Michael Scott on 07/07/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -/* Finite Field arithmetic Fp^4 functions */ - -/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1)) */ - -final class FP4 { - private final var a:FP2 - private final var b:FP2 - - /* constructors */ - init(_ c:Int) - { - a=FP2(c) - b=FP2(0) - } - - init(_ x:FP4) - { - a=FP2(x.a) - b=FP2(x.b) - } - - init(_ c:FP2,_ d:FP2) - { - a=FP2(c) - b=FP2(d) - } - - init(_ c:FP2) - { - a=FP2(c) - b=FP2(0) - } - /* reduce all components of this mod Modulus */ - func reduce() - { - a.reduce() - b.reduce() - } - /* normalise all components of this mod Modulus */ - func norm() - { - a.norm() - b.norm() - } - /* test this==0 ? */ - func iszilch() -> Bool - { - reduce() - return a.iszilch() && b.iszilch() - } - /* test this==1 ? */ - func isunity() -> Bool - { - let one=FP2(1); - return a.equals(one) && b.iszilch() - } - - /* test is w real? That is in a+ib test b is zero */ - func isreal() -> Bool - { - return b.iszilch(); - } - /* extract real part a */ - func real() -> FP2 - { - return a; - } - - func geta() -> FP2 - { - return a; - } - /* extract imaginary part b */ - func getb() -> FP2 - { - return b; - } - /* test self=x? */ - func equals(_ x:FP4) -> Bool - { - return a.equals(x.a) && b.equals(x.b) - } - /* copy self=x */ - func copy(_ x:FP4) - { - a.copy(x.a) - b.copy(x.b) - } - /* set this=0 */ - func zero() - { - a.zero() - b.zero() - } - /* set this=1 */ - func one() - { - a.one() - b.zero() - } - /* set self=-self */ - func neg() - { - let m=FP2(a) - let t=FP2(0) - m.add(b) - m.neg() - m.norm() - t.copy(m); t.add(b) - b.copy(m) - b.add(a) - a.copy(t) - } - /* self=conjugate(self) */ - func conj() - { - b.neg(); b.norm() - } - /* this=-conjugate(this) */ - func nconj() - { - a.neg(); a.norm() - } - /* self+=x */ - func add(_ x:FP4) - { - a.add(x.a) - b.add(x.b) - } - /* self-=x */ - func sub(_ x:FP4) - { - let m=FP4(x) - m.neg() - add(m) - } - - /* self*=s where s is FP2 */ - func pmul(_ s:FP2) - { - a.mul(s) - b.mul(s) - } - /* self*=c where c is int */ - func imul(_ c:Int) - { - a.imul(c) - b.imul(c) - } - /* self*=self */ - func sqr() - { - norm(); - - let t1=FP2(a) - let t2=FP2(b) - let t3=FP2(a) - - t3.mul(b) - t1.add(b) - t2.mul_ip() - - t2.add(a) - a.copy(t1) - - a.mul(t2) - - t2.copy(t3) - t2.mul_ip() - t2.add(t3) - t2.neg() - a.add(t2) - - b.copy(t3) - b.add(t3) - - norm() - } - /* self*=y */ - func mul(_ y:FP4) - { - norm(); - - let t1=FP2(a) - let t2=FP2(b) - let t3=FP2(0) - let t4=FP2(b) - - t1.mul(y.a) - t2.mul(y.b) - t3.copy(y.b) - t3.add(y.a) - t4.add(a) - - t4.mul(t3) - t4.sub(t1) - t4.norm() - - b.copy(t4) - b.sub(t2) - t2.mul_ip() - a.copy(t2) - a.add(t1) - - norm() - } - /* convert this to hex string */ - func toString() -> String - { - return ("["+a.toString()+","+b.toString()+"]") - } - - func toRawString() -> String - { - return ("["+a.toRawString()+","+b.toRawString()+"]") - } - /* self=1/self */ - func inverse() - { - norm(); - - let t1=FP2(a) - let t2=FP2(b) - - t1.sqr() - t2.sqr() - t2.mul_ip() - t1.sub(t2) - t1.inverse() - a.mul(t1) - t1.neg() - b.mul(t1) - } - - /* self*=i where i = sqrt(-1+sqrt(-1)) */ - func times_i() - { - norm(); - let s=FP2(b) - let t=FP2(b) - s.times_i() - t.add(s) - t.norm() - b.copy(a) - a.copy(t) - } - - /* self=self^p using Frobenius */ - func frob(_ f:FP2) - { - a.conj() - b.conj() - b.mul(f) - } - /* self=self^e */ - func pow(_ e:BIG) -> FP4 - { - norm() - e.norm() - let w=FP4(self) - let z=BIG(e) - let r=FP4(1) - while (true) - { - let 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 xtr_A(_ w:FP4,_ y:FP4,_ z:FP4) - { - let r=FP4(w) - let t=FP4(w) - r.sub(y) - r.pmul(a) - t.add(y) - t.pmul(b) - t.times_i() - - copy(r) - add(t) - add(z) - - norm() - } - /* XTR xtr_d function */ - func xtr_D() - { - let w=FP4(self) - sqr(); w.conj() - w.add(w) - sub(w) - reduce() - } - /* r=x^n using XTR method on traces of FP12s */ - func xtr_pow(_ n:BIG) -> FP4 - { - let a=FP4(3) - let b=FP4(self) - let c=FP4(b) - c.xtr_D() - let t=FP4(0) - let r=FP4(0) - - n.norm(); - let par=n.parity() - let v=BIG(n); v.fshr(1) - if par==0 {v.dec(1); v.norm()} - - let nb=v.nbits() - //for i in (0...nb-1).reverse() - var i=nb-1 - //for var i=nb-1;i>=0;i-- - while i>=0 - { - if (v.bit(UInt(i)) != 1) - { - t.copy(b) - conj() - c.conj() - b.xtr_A(a,self,c) - 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,self,t) - c.xtr_D() - } - i-=1 - } - 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 xtr_pow2(_ ck:FP4,_ ckml:FP4,_ ckm2l:FP4,_ a:BIG,_ b:BIG) -> FP4 - { - a.norm(); b.norm() - let e=BIG(a) - let d=BIG(b) - let w=BIG(0) - - let cu=FP4(ck) // can probably be passed in w/o copying - let cv=FP4(self) - let cumv=FP4(ckml) - let cum2v=FP4(ckm2l) - var r=FP4(0) - let t=FP4(0) - - var f2:Int=0 - while d.parity()==0 && e.parity()==0 - { - d.fshr(1); - e.fshr(1); - f2 += 1; - } - - while (BIG.comp(d,e) != 0) - { - if BIG.comp(d,e)>0 - { - w.copy(e); w.imul(4); w.norm() - if BIG.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 BIG.comp(d,e)<0 - { - w.copy(d); w.imul(4); w.norm() - if BIG.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 _ in 0 ..< f2 - {r.xtr_D()} - r=r.xtr_pow(d) - return r - } - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/gcm.swift ---------------------------------------------------------------------- diff --git a/version22/swift/gcm.swift b/version22/swift/gcm.swift deleted file mode 100644 index 15a6657..0000000 --- a/version22/swift/gcm.swift +++ /dev/null @@ -1,326 +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. -*/ - -// -// gcm.swift -// -// Created by Michael Scott on 23/06/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -import Foundation - -/* -* 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 -*/ - -final class GCM { - static let NB:Int=4 - static let GCM_ACCEPTING_HEADER:Int=0 - static let GCM_ACCEPTING_CIPHER:Int=1 - static let GCM_NOT_ACCEPTING_MORE:Int=2 - static let GCM_FINISHED:Int=3 - static let GCM_ENCRYPTING:Int=0 - static let GCM_DECRYPTING:Int=1 - - private var table=[[UInt32]](repeating: [UInt32](repeating: 0,count: 4),count: 128) /* 2k bytes */ - private var stateX=[UInt8](repeating: 0,count: 16) - private var Y_0=[UInt8](repeating: 0,count: 16) - - private var counter:Int=0 - private var lenA=[UInt32](repeating: 0,count: 2) - private var lenC=[UInt32](repeating: 0,count: 2) - private var status:Int=0 - private var a=AES() - - private static func pack(_ b: [UInt8]) -> UInt32 - { /* pack bytes into a 32-bit Word */ - var r=((UInt32(b[0])&0xff)<<24)|((UInt32(b[1])&0xff)<<16) - r = r|((UInt32(b[2])&0xff)<<8)|(UInt32(b[3])&0xff) - return r - } - - private static func unpack(_ a: UInt32) -> [UInt8] - { /* unpack bytes from a word */ - let b:[UInt8]=[UInt8((a>>24)&0xff),UInt8((a>>16)&0xff),UInt8((a>>8)&0xff),UInt8(a&0xff)]; - return b - } - - private func precompute(_ H: [UInt8]) - { - var b=[UInt8](repeating: 0,count: 4) - var j=0 - for i in 0 ..< GCM.NB - { - b[0]=H[j]; b[1]=H[j+1]; b[2]=H[j+2]; b[3]=H[j+3]; - table[0][i]=GCM.pack(b); - j+=4 - } - for i in 1 ..< 128 - { - var c:UInt32=0 - for j in 0 ..< GCM.NB {table[i][j]=c|(table[i-1][j])>>1; c=table[i-1][j]<<31;} - if c != 0 {table[i][0]^=0xE1000000} /* irreducible polynomial */ - } - } - - private func gf2mul() - { /* gf2m mul - Z=H*X mod 2^128 */ - var P=[UInt32](repeating: 0,count: 4) - - for i in 0 ..< 4 {P[i]=0} - var j=8; var m=0; - for i in 0 ..< 128 - { - j-=1 - var c=UInt32((stateX[m]>>UInt8(j))&1); c = ( ~c ) + 1 - for k in 0 ..< GCM.NB {P[k]^=(table[i][k] & c)} - if (j==0) - { - j=8; m += 1; - if (m==16) {break} - } - } - j=0 - for i in 0 ..< GCM.NB - { - var b=GCM.unpack(P[i]) - stateX[j]=b[0]; stateX[j+1]=b[1]; stateX[j+2]=b[2]; stateX[j+3]=b[3]; - j+=4 - } - } - private func wrap() - { /* Finish off GHASH */ - var F=[UInt32](repeating: 0,count: 4) - var L=[UInt8](repeating: 0,count: 16) - - /* convert lengths from bytes to bits */ - F[0]=(lenA[0]<<3)|(lenA[1]&0xE0000000)>>29 - F[1]=lenA[1]<<3; - F[2]=(lenC[0]<<3)|(lenC[1]&0xE0000000)>>29 - F[3]=lenC[1]<<3; - var j=0 - for i in 0 ..< GCM.NB - { - var 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 in 0 ..< 16 {stateX[i]^=L[i]} - gf2mul() - } - - private func ghash(_ plain: [UInt8],_ len: Int) -> Bool - { - // var B=[UInt8](count:16,repeatedValue:0) - - if status==GCM.GCM_ACCEPTING_HEADER {status=GCM.GCM_ACCEPTING_CIPHER} - if (status != GCM.GCM_ACCEPTING_CIPHER) {return false} - - var j=0; - while (j<len) - { - for i in 0 ..< 16 - { - stateX[i]^=plain[j]; - j+=1; - lenC[1]+=1; if lenC[1]==0 {lenC[0]+=1} - if j>=len {break;} - } - gf2mul(); - } - if len%16 != 0 {status=GCM.GCM_NOT_ACCEPTING_MORE} - return true; - } - - /* Initialize GCM mode */ - func init_it(_ key: [UInt8],_ niv: Int,_ iv: [UInt8]) - { /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */ - var H=[UInt8](repeating: 0,count: 16) - - for i in 0 ..< 16 {H[i]=0; stateX[i]=0} - - a.init_it(AES.ECB,key,iv) - a.ecb_encrypt(&H); /* E(K,0) */ - precompute(H) - - lenA[0]=0;lenC[0]=0;lenA[1]=0;lenC[1]=0; - if (niv==12) - { - for i in 0 ..< 12 {a.f[i]=iv[i]} - var b=GCM.unpack(UInt32(1)) - a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3]; /* initialise IV */ - for i in 0 ..< 16 {Y_0[i]=a.f[i]} - } - else - { - status=GCM.GCM_ACCEPTING_CIPHER; - ghash(iv,niv) /* GHASH(H,0,IV) */ - wrap() - for i in 0 ..< 16 {a.f[i]=stateX[i];Y_0[i]=a.f[i];stateX[i]=0} - lenA[0]=0;lenC[0]=0;lenA[1]=0;lenC[1]=0; - } - status=GCM.GCM_ACCEPTING_HEADER; - } - - /* Add Header data - included but not encrypted */ - func add_header(_ header: [UInt8],_ len: Int) -> Bool - { /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */ - if status != GCM.GCM_ACCEPTING_HEADER {return false} - - var j=0 - while (j<len) - { - for i in 0 ..< 16 - { - stateX[i]^=header[j]; - j+=1; - lenA[1]+=1; if lenA[1]==0 {lenA[0]+=1} - if j>=len {break} - } - gf2mul(); - } - if len%16 != 0 {status=GCM.GCM_ACCEPTING_CIPHER} - return true; - } - /* Add Plaintext - included and encrypted */ - func add_plain(_ plain: [UInt8],_ len: Int) -> [UInt8] - { - var B=[UInt8](repeating: 0,count: 16) - var b=[UInt8](repeating: 0,count: 4) - - var cipher=[UInt8](repeating: 0,count: len) - var counter:UInt32=0 - if status == GCM.GCM_ACCEPTING_HEADER {status=GCM.GCM_ACCEPTING_CIPHER} - if status != GCM.GCM_ACCEPTING_CIPHER {return [UInt8]()} - - var j=0 - while (j<len) - { - - b[0]=a.f[12]; b[1]=a.f[13]; b[2]=a.f[14]; b[3]=a.f[15]; - counter=GCM.pack(b); - counter+=1; - b=GCM.unpack(counter); - a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3]; /* increment counter */ - for i in 0 ..< 16 {B[i]=a.f[i]} - a.ecb_encrypt(&B); /* encrypt it */ - - for i in 0 ..< 16 - { - cipher[j]=(plain[j]^B[i]); - stateX[i]^=cipher[j]; - j+=1; - lenC[1]+=1; if lenC[1]==0 {lenC[0]+=1} - if j>=len {break} - } - gf2mul(); - } - if len%16 != 0 {status=GCM.GCM_NOT_ACCEPTING_MORE} - return cipher; - } - /* Add Ciphertext - decrypts to plaintext */ - func add_cipher(_ cipher: [UInt8],_ len: Int) -> [UInt8] - { - var B=[UInt8](repeating: 0,count: 16) - var b=[UInt8](repeating: 0,count: 4) - - var plain=[UInt8](repeating: 0,count: len) - var counter:UInt32=0 - - if status==GCM.GCM_ACCEPTING_HEADER {status=GCM.GCM_ACCEPTING_CIPHER} - if status != GCM.GCM_ACCEPTING_CIPHER {return [UInt8]()} - - var j=0 - while (j<len) - { - - b[0]=a.f[12]; b[1]=a.f[13]; b[2]=a.f[14]; b[3]=a.f[15]; - counter=GCM.pack(b); - counter+=1; - b=GCM.unpack(counter); - a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3]; /* increment counter */ - for i in 0 ..< 16 {B[i]=a.f[i]} - a.ecb_encrypt(&B); /* encrypt it */ - for i in 0 ..< 16 - { - let oc=cipher[j] - plain[j]=(cipher[j]^B[i]); - stateX[i]^=oc; - j+=1; - lenC[1]+=1; if lenC[1]==0 {lenC[0]+=1} - if j>=len {break} - } - gf2mul() - } - if len%16 != 0 {status=GCM.GCM_NOT_ACCEPTING_MORE} - return plain; - } - - /* Finish and extract Tag */ - func finish(_ extract: Bool) -> [UInt8] - { /* Finish off GHASH and extract tag (MAC) */ - var tag=[UInt8](repeating: 0,count: 16) - - wrap(); - /* extract tag */ - if (extract) - { - a.ecb_encrypt(&Y_0); /* E(K,Y0) */ - for i in 0 ..< 16 {Y_0[i]^=stateX[i]} - for i in 0 ..< 16 {tag[i]=Y_0[i];Y_0[i]=0;stateX[i]=0;} - } - status=GCM.GCM_FINISHED; - a.end(); - return tag; - } - - static func hex2bytes(_ s: String) -> [UInt8] - { - var array=Array(arrayLiteral: s) - let len=array.count; - var data=[UInt8](repeating: 0,count: len/2) - - var i=0 - while (i<len) - { - data[i / 2] = UInt8(strtoul(String(array[i]),nil,16)<<4)+UInt8(strtoul(String(array[i+1]),nil,16)) - i+=2 - } - return data; - } - - -} - http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/hash256.swift ---------------------------------------------------------------------- diff --git a/version22/swift/hash256.swift b/version22/swift/hash256.swift deleted file mode 100644 index 6140da5..0000000 --- a/version22/swift/hash256.swift +++ /dev/null @@ -1,188 +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. -*/ - -// -// hash256.swift - Implementation of SHA-256 -// -// Created by Michael Scott on 17/06/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// SHA256 Implementation -// - -final class HASH256{ - - private var length=[UInt32](repeating: 0,count: 2) - private var h=[UInt32](repeating: 0,count: 8) - private var w=[UInt32](repeating: 0,count: 64) - static let H0:UInt32=0x6A09E667 - static let H1:UInt32=0xBB67AE85 - static let H2:UInt32=0x3C6EF372 - static let H3:UInt32=0xA54FF53A - static let H4:UInt32=0x510E527F - static let H5:UInt32=0x9B05688C - static let H6:UInt32=0x1F83D9AB - static let H7:UInt32=0x5BE0CD19 - - static let len:Int=32 - - static let 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] - - - private static func S(_ n: UInt32,_ x: UInt32) -> UInt32 - { - return ((x>>n)|(x<<(32-n))) - } - - private static func R(_ n: UInt32,_ x: UInt32) -> UInt32 - { - return (x>>n) - } - - private static func Ch(_ x: UInt32,_ y: UInt32,_ z:UInt32) -> UInt32 - { - return ((x&y)^(~(x)&z)) - } - - private static func Maj(_ x: UInt32,_ y: UInt32,_ z:UInt32) -> UInt32 - { - return ((x&y)^(x&z)^(y&z)) - } - - private static func Sig0(_ x: UInt32) -> UInt32 - { - return (S(2,x)^S(13,x)^S(22,x)) - } - - private static func Sig1(_ x: UInt32) -> UInt32 - { - return (S(6,x)^S(11,x)^S(25,x)) - } - - private static func theta0(_ x: UInt32) -> UInt32 - { - return (S(7,x)^S(18,x)^R(3,x)) - } - - private static func theta1(_ x: UInt32) -> UInt32 - { - return (S(17,x)^S(19,x)^R(10,x)) - } - - private func transform() - { /* basic transformation step */ - var a,b,c,d,e,f,g,hh,t1,t2 :UInt32 - for j in 16 ..< 64 - { - w[j]=HASH256.theta1(w[j-2])&+w[j-7]&+HASH256.theta0(w[j-15])&+w[j-16] - } - a=h[0]; b=h[1]; c=h[2]; d=h[3] - e=h[4]; f=h[5]; g=h[6]; hh=h[7] - - for j in 0 ..< 64 - { /* 64 times - mush it up */ - t1=hh&+HASH256.Sig1(e)&+HASH256.Ch(e,f,g)&+HASH256.K[j]&+w[j] - t2=HASH256.Sig0(a)&+HASH256.Maj(a,b,c) - hh=g; g=f; f=e; - e=d&+t1; - d=c; - c=b; - b=a; - a=t1&+t2; - } - h[0]=h[0]&+a; h[1]=h[1]&+b; h[2]=h[2]&+c; h[3]=h[3]&+d - h[4]=h[4]&+e; h[5]=h[5]&+f; h[6]=h[6]&+g; h[7]=h[7]&+hh; - } - - /* Re-Initialise Hash function */ - func init_it() - { /* initialise */ - for i in 0 ..< 64 {w[i]=0} - length[0]=0; length[1]=0 - h[0]=HASH256.H0; - h[1]=HASH256.H1; - h[2]=HASH256.H2; - h[3]=HASH256.H3; - h[4]=HASH256.H4; - h[5]=HASH256.H5; - h[6]=HASH256.H6; - h[7]=HASH256.H7; - } - - init() - { - init_it() - } - - /* process a single byte */ - func process(_ byt: UInt8) - { /* process the next message byte */ - let cnt=Int((length[0]/32)%16) - w[cnt]<<=8; - w[cnt]|=(UInt32(byt)&0xFF); - length[0]+=8; - if (length[0]==0) { length[1] += 1; length[0]=0 } - if ((length[0]%512)==0) {transform()} - } - - /* process an array of bytes */ - func process_array(_ b: [UInt8]) - { - for i in 0 ..< b.count {process((b[i]))} - } - - /* process a 32-bit integer */ - func process_num(_ n:Int32) - { - process(UInt8((n>>24)&0xff)) - process(UInt8((n>>16)&0xff)) - process(UInt8((n>>8)&0xff)) - process(UInt8(n&0xff)) - } - - /* Generate 32-byte Hash */ - func hash() -> [UInt8] - { /* pad message and finish - supply digest */ - var digest=[UInt8](repeating: 0,count: 32) - - let len0=length[0] - let len1=length[1] - process(0x80); - while ((length[0]%512) != 448) {process(0)} - w[14]=len1 - w[15]=len0; - transform() - for i in 0 ..< HASH256.len - { /* convert to bytes */ - let r=(8*(3-UInt32(i)%4)); - digest[i]=UInt8((h[i/4]>>r) & 0xff); - } - init_it(); - return digest; - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/hash384.swift ---------------------------------------------------------------------- diff --git a/version22/swift/hash384.swift b/version22/swift/hash384.swift deleted file mode 100644 index de89d4c..0000000 --- a/version22/swift/hash384.swift +++ /dev/null @@ -1,198 +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. -*/ - -// -// hash384.swift - Implementation of SHA-384 -// -// Created by Michael Scott on 29/03/2016. -// Copyright © 2016 Michael Scott. All rights reserved. -// - -import Foundation - -final class HASH384{ - - private var length=[UInt64](repeating: 0,count: 2) - private var h=[UInt64](repeating: 0,count: 8) - private var w=[UInt64](repeating: 0,count: 80) - static let H0:UInt64=0xcbbb9d5dc1059ed8 - static let H1:UInt64=0x629a292a367cd507 - static let H2:UInt64=0x9159015a3070dd17 - static let H3:UInt64=0x152fecd8f70e5939 - static let H4:UInt64=0x67332667ffc00b31 - static let H5:UInt64=0x8eb44a8768581511 - static let H6:UInt64=0xdb0c2e0d64f98fa7 - static let H7:UInt64=0x47b5481dbefa4fa4 - - static let len:Int=48 - - static let K:[UInt64]=[ - 0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc, - 0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118, - 0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694, - 0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65, - 0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5, - 0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4, - 0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70, - 0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df, - 0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b, - 0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30, - 0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8, - 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3, - 0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec, - 0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b, - 0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178, - 0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b, - 0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c, - 0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817] - - private static func S(_ n: UInt32,_ x: UInt64) -> UInt64 - { - return ((x>>UInt64(n))|(x<<(64-UInt64(n)))) - } - - private static func R(_ n: UInt32,_ x: UInt64) -> UInt64 - { - return (x>>UInt64(n)) - } - - private static func Ch(_ x: UInt64,_ y: UInt64,_ z:UInt64) -> UInt64 - { - return ((x&y)^(~(x)&z)) - } - - private static func Maj(_ x: UInt64,_ y: UInt64,_ z:UInt64) -> UInt64 - { - return ((x&y)^(x&z)^(y&z)) - } - - private static func Sig0(_ x: UInt64) -> UInt64 - { - return (S(28,x)^S(34,x)^S(39,x)) - } - - private static func Sig1(_ x: UInt64) -> UInt64 - { - return (S(14,x)^S(18,x)^S(41,x)) - } - - private static func theta0(_ x: UInt64) -> UInt64 - { - return (S(1,x)^S(8,x)^R(7,x)) - } - - private static func theta1(_ x: UInt64) -> UInt64 - { - return (S(19,x)^S(61,x)^R(6,x)) - } - - private func transform() - { /* basic transformation step */ - var a,b,c,d,e,f,g,hh,t1,t2 :UInt64 - for j in 16 ..< 80 - { - w[j]=HASH384.theta1(w[j-2])&+w[j-7]&+HASH384.theta0(w[j-15])&+w[j-16] - } - a=h[0]; b=h[1]; c=h[2]; d=h[3] - e=h[4]; f=h[5]; g=h[6]; hh=h[7] - - for j in 0 ..< 80 - { /* 64 times - mush it up */ - t1=hh&+HASH384.Sig1(e)&+HASH384.Ch(e,f,g)&+HASH384.K[j]&+w[j] - t2=HASH384.Sig0(a)&+HASH384.Maj(a,b,c) - hh=g; g=f; f=e; - e=d&+t1; - d=c; - c=b; - b=a; - a=t1&+t2; - } - h[0]=h[0]&+a; h[1]=h[1]&+b; h[2]=h[2]&+c; h[3]=h[3]&+d - h[4]=h[4]&+e; h[5]=h[5]&+f; h[6]=h[6]&+g; h[7]=h[7]&+hh; - } - - /* Re-Initialise Hash function */ - func init_it() - { /* initialise */ - for i in 0 ..< 80 {w[i]=0} - length[0]=0; length[1]=0 - h[0]=HASH384.H0; - h[1]=HASH384.H1; - h[2]=HASH384.H2; - h[3]=HASH384.H3; - h[4]=HASH384.H4; - h[5]=HASH384.H5; - h[6]=HASH384.H6; - h[7]=HASH384.H7; - } - - init() - { - init_it() - } - - /* process a single byte */ - func process(_ byt: UInt8) - { /* process the next message byte */ - let cnt=Int((length[0]/64)%16) - w[cnt]<<=8; - w[cnt]|=(UInt64(byt)&0xFF); - length[0]+=8; - if (length[0]==0) { length[1] += 1; length[0]=0 } - if ((length[0]%1024)==0) {transform()} - } - - /* process an array of bytes */ - func process_array(_ b: [UInt8]) - { - for i in 0 ..< b.count {process((b[i]))} - } - - /* process a 32-bit integer */ - func process_num(_ n:Int32) - { - process(UInt8((n>>24)&0xff)) - process(UInt8((n>>16)&0xff)) - process(UInt8((n>>8)&0xff)) - process(UInt8(n&0xff)) - } - - /* Generate 48-byte Hash */ - func hash() -> [UInt8] - { /* pad message and finish - supply digest */ - var digest=[UInt8](repeating: 0,count: 48) - - let len0=length[0] - let len1=length[1] - process(0x80); - while ((length[0]%1024) != 896) {process(0)} - w[14]=len1 - w[15]=len0; - transform() - for i in 0 ..< HASH384.len - { /* convert to bytes */ - digest[i]=UInt8((h[i/8]>>(8*(7-UInt64(i)%8))) & 0xff); - } - init_it(); - return digest; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/hash512.swift ---------------------------------------------------------------------- diff --git a/version22/swift/hash512.swift b/version22/swift/hash512.swift deleted file mode 100644 index 634f944..0000000 --- a/version22/swift/hash512.swift +++ /dev/null @@ -1,198 +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. -*/ - -// -// hash512.swift - Implementation of SHA-512 -// -// Created by Michael Scott on 29/03/2016. -// Copyright © 2016 Michael Scott. All rights reserved. -// - -import Foundation - -final class HASH512{ - - private var length=[UInt64](repeating: 0,count: 2) - private var h=[UInt64](repeating: 0,count: 8) - private var w=[UInt64](repeating: 0,count: 80) - static let H0:UInt64=0x6a09e667f3bcc908 - static let H1:UInt64=0xbb67ae8584caa73b - static let H2:UInt64=0x3c6ef372fe94f82b - static let H3:UInt64=0xa54ff53a5f1d36f1 - static let H4:UInt64=0x510e527fade682d1 - static let H5:UInt64=0x9b05688c2b3e6c1f - static let H6:UInt64=0x1f83d9abfb41bd6b - static let H7:UInt64=0x5be0cd19137e2179 - - static let len:Int=64 - - static let K:[UInt64]=[ - 0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc, - 0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118, - 0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694, - 0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65, - 0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5, - 0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4, - 0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70, - 0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df, - 0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b, - 0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30, - 0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8, - 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3, - 0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec, - 0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b, - 0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178, - 0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b, - 0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c, - 0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817] - - private static func S(_ n: UInt32,_ x: UInt64) -> UInt64 - { - return ((x>>UInt64(n))|(x<<(64-UInt64(n)))) - } - - private static func R(_ n: UInt32,_ x: UInt64) -> UInt64 - { - return (x>>UInt64(n)) - } - - private static func Ch(_ x: UInt64,_ y: UInt64,_ z:UInt64) -> UInt64 - { - return ((x&y)^(~(x)&z)) - } - - private static func Maj(_ x: UInt64,_ y: UInt64,_ z:UInt64) -> UInt64 - { - return ((x&y)^(x&z)^(y&z)) - } - - private static func Sig0(_ x: UInt64) -> UInt64 - { - return (S(28,x)^S(34,x)^S(39,x)) - } - - private static func Sig1(_ x: UInt64) -> UInt64 - { - return (S(14,x)^S(18,x)^S(41,x)) - } - - private static func theta0(_ x: UInt64) -> UInt64 - { - return (S(1,x)^S(8,x)^R(7,x)) - } - - private static func theta1(_ x: UInt64) -> UInt64 - { - return (S(19,x)^S(61,x)^R(6,x)) - } - - private func transform() - { /* basic transformation step */ - var a,b,c,d,e,f,g,hh,t1,t2 :UInt64 - for j in 16 ..< 80 - { - w[j]=HASH512.theta1(w[j-2])&+w[j-7]&+HASH512.theta0(w[j-15])&+w[j-16] - } - a=h[0]; b=h[1]; c=h[2]; d=h[3] - e=h[4]; f=h[5]; g=h[6]; hh=h[7] - - for j in 0 ..< 80 - { /* 64 times - mush it up */ - t1=hh&+HASH512.Sig1(e)&+HASH512.Ch(e,f,g)&+HASH512.K[j]&+w[j] - t2=HASH512.Sig0(a)&+HASH512.Maj(a,b,c) - hh=g; g=f; f=e; - e=d&+t1; - d=c; - c=b; - b=a; - a=t1&+t2; - } - h[0]=h[0]&+a; h[1]=h[1]&+b; h[2]=h[2]&+c; h[3]=h[3]&+d - h[4]=h[4]&+e; h[5]=h[5]&+f; h[6]=h[6]&+g; h[7]=h[7]&+hh; - } - - /* Re-Initialise Hash function */ - func init_it() - { /* initialise */ - for i in 0 ..< 80 {w[i]=0} - length[0]=0; length[1]=0 - h[0]=HASH512.H0; - h[1]=HASH512.H1; - h[2]=HASH512.H2; - h[3]=HASH512.H3; - h[4]=HASH512.H4; - h[5]=HASH512.H5; - h[6]=HASH512.H6; - h[7]=HASH512.H7; - } - - init() - { - init_it() - } - - /* process a single byte */ - func process(_ byt: UInt8) - { /* process the next message byte */ - let cnt=Int((length[0]/64)%16) - w[cnt]<<=8; - w[cnt]|=(UInt64(byt)&0xFF); - length[0]+=8; - if (length[0]==0) { length[1] += 1; length[0]=0 } - if ((length[0]%1024)==0) {transform()} - } - - /* process an array of bytes */ - func process_array(_ b: [UInt8]) - { - for i in 0 ..< b.count {process((b[i]))} - } - - /* process a 32-bit integer */ - func process_num(_ n:Int32) - { - process(UInt8((n>>24)&0xff)) - process(UInt8((n>>16)&0xff)) - process(UInt8((n>>8)&0xff)) - process(UInt8(n&0xff)) - } - - /* Generate 48-byte Hash */ - func hash() -> [UInt8] - { /* pad message and finish - supply digest */ - var digest=[UInt8](repeating: 0,count: 64) - - let len0=length[0] - let len1=length[1] - process(0x80); - while ((length[0]%1024) != 896) {process(0)} - w[14]=len1 - w[15]=len0; - transform() - for i in 0 ..< HASH512.len - { /* convert to bytes */ - digest[i]=UInt8((h[i/8]>>(8*(7-UInt64(i)%8))) & 0xff); - } - init_it(); - return digest; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/main.swift ---------------------------------------------------------------------- diff --git a/version22/swift/main.swift b/version22/swift/main.swift deleted file mode 100644 index e464a0e..0000000 --- a/version22/swift/main.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// main.swift -// -// Created by Michael Scott on 12/06/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -BenchtestPAIR() -BenchtestEC() -TestRSA() -TestECDH() -TestMPIN() - http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/swift/mpin.swift ---------------------------------------------------------------------- diff --git a/version22/swift/mpin.swift b/version22/swift/mpin.swift deleted file mode 100644 index c4bc28e..0000000 --- a/version22/swift/mpin.swift +++ /dev/null @@ -1,833 +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.swift -// -// Created by Michael Scott on 08/07/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - - -import Foundation - -final public class MPIN -{ - static public let EFS=Int(ROM.MODBYTES) - static public let EGS=Int(ROM.MODBYTES) - static public let PAS:Int=16 - static let INVALID_POINT:Int = -14 - static let BAD_PARAMS:Int = -11 - static let WRONG_ORDER:Int = -18 - static public let BAD_PIN:Int = -19 - static public let SHA256=32 - static public let SHA384=48 - static public let SHA512=64 - - /* Configure your PIN here */ - - static let MAXPIN:Int32 = 10000 // PIN less than this - static let PBLEN:Int32 = 14 // Number of bits in PIN - static let TS:Int = 10 // 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) - static let TRAP:Int = 200 // 200 for 4 digit PIN, 2000 for 6-digit PIN - approx 2*sqrt(MAXPIN) - - static public let HASH_TYPE=SHA256 - - private static func mpin_hash(_ sha:Int,_ c: FP4,_ U: ECP) -> [UInt8] - { - var w=[UInt8](repeating: 0,count: EFS) - var t=[UInt8](repeating: 0,count: 6*EFS) - var h=[UInt8]() - - c.geta().getA().toBytes(&w); for i in 0 ..< EFS {t[i]=w[i]} - c.geta().getB().toBytes(&w); for i in EFS ..< 2*EFS {t[i]=w[i-EFS]} - c.getb().getA().toBytes(&w); for i in 2*EFS ..< 3*EFS {t[i]=w[i-2*EFS]} - c.getb().getB().toBytes(&w); for i in 3*EFS ..< 4*EFS {t[i]=w[i-3*EFS]} - - U.getX().toBytes(&w); for i in 4*EFS ..< 5*EFS {t[i]=w[i-4*EFS]} - U.getY().toBytes(&w); for i in 5*EFS ..< 6*EFS {t[i]=w[i-5*EFS]} - - if sha==SHA256 - { - let H=HASH256() - H.process_array(t) - h=H.hash() - } - if sha==SHA384 - { - let H=HASH384() - H.process_array(t) - h=H.hash() - } - if sha==SHA512 - { - let H=HASH512() - H.process_array(t) - h=H.hash() - } - if h.isEmpty {return h} - var R=[UInt8](repeating: 0,count: PAS) - for i in 0 ..< PAS {R[i]=h[i]} - return R - } - - // Hash number (optional) and string to point on curve - - private static func hashit(_ sha:Int,_ n:Int32,_ ID:[UInt8]) -> [UInt8] - { - var R=[UInt8]() - if sha==SHA256 - { - let H=HASH256() - if n != 0 {H.process_num(n)} - H.process_array(ID) - R=H.hash() - } - if sha==SHA384 - { - let H=HASH384() - if n != 0 {H.process_num(n)} - H.process_array(ID) - R=H.hash() - } - if sha==SHA512 - { - let H=HASH512() - if n != 0 {H.process_num(n)} - H.process_array(ID) - R=H.hash() - } - if R.isEmpty {return R} - let RM=Int(ROM.MODBYTES) - var W=[UInt8](repeating: 0,count: RM) - if sha >= RM - { - for i in 0 ..< RM {W[i]=R[i]} - } - else - { - for i in 0 ..< sha {W[i]=R[i]} - } - return W - } - - static func mapit(_ h:[UInt8]) -> ECP - { - let q=BIG(ROM.Modulus) - let x=BIG.fromBytes(h) - x.mod(q) - var P=ECP(x,0) - while (true) - { - if !P.is_infinity() {break} - x.inc(1); x.norm(); - P=ECP(x,0); - } - if ROM.CURVE_PAIRING_TYPE != ROM.BN_CURVE { - let c=BIG(ROM.CURVE_Cof) - P=P.mul(c) - } - - return P - } - - // needed for SOK - static func mapit2(_ h:[UInt8]) -> ECP2 - { - let q=BIG(ROM.Modulus) - var x=BIG.fromBytes(h) - let one=BIG(1) - var Q=ECP2() - x.mod(q); - while (true) - { - let X=FP2(one,x); - Q=ECP2(X); - if !Q.is_infinity() {break} - x.inc(1); x.norm(); - } - // Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez - let Fra=BIG(ROM.CURVE_Fra); - let Frb=BIG(ROM.CURVE_Frb); - let X=FP2(Fra,Frb); - x=BIG(ROM.CURVE_Bnx); - - let T=ECP2(); T.copy(Q) - T.mul(x); T.neg() - let K=ECP2(); 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 - static public func today() -> Int32 - { - let date=Date() - return (Int32(date.timeIntervalSince1970/(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 - static func map(_ u:BIG,_ cb:Int) -> ECP - { - let x=BIG(u) - let p=BIG(ROM.Modulus) - x.mod(p) - var P=ECP(x,cb) - while (true) - { - if !P.is_infinity() {break} - x.inc(1); x.norm() - P=ECP(x,cb) - } - return P - } - - // returns u derived from P. Random value in range 1 to return value should then be added to u - static func unmap(_ u:inout BIG,_ P:ECP) -> Int - { - let s=P.getS() - var r:Int32=0 - let x=P.getX() - u.copy(x) - var R=ECP() - while (true) - { - u.dec(1); u.norm() - r += 1 - R=ECP(u,s) - if !R.is_infinity() {break} - } - return Int(r) - } - - static public func HASH_ID(_ sha:Int,_ ID:[UInt8]) -> [UInt8] - { - return hashit(sha,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 - static public func ENCODING(_ rng:RAND,_ E:inout [UInt8]) -> Int - { - var T=[UInt8](repeating: 0,count: EFS) - - for i in 0 ..< EFS {T[i]=E[i+1]} - var u=BIG.fromBytes(T); - for i in 0 ..< EFS {T[i]=E[i+EFS+1]} - var v=BIG.fromBytes(T) - - let P=ECP(u,v); - if P.is_infinity() {return INVALID_POINT} - - let p=BIG(ROM.Modulus) - u=BIG.randomnum(p,rng) - - var su=rng.getByte(); - su%=2 - - let W=MPIN.map(u,Int(su)) - P.sub(W); - let sv=P.getS(); - let rn=MPIN.unmap(&v,P) - let m=rng.getByte(); - let incr=1+Int(m)%rn - v.inc(incr) - E[0]=(su+UInt8(2*sv)) - u.toBytes(&T) - for i in 0 ..< EFS {E[i+1]=T[i]} - v.toBytes(&T) - for i in 0 ..< EFS {E[i+EFS+1]=T[i]} - - return 0; - } - - static public func DECODING(_ D:inout [UInt8]) -> Int - { - var T=[UInt8](repeating: 0,count: EFS) - - if (D[0]&0x04) != 0 {return INVALID_POINT} - - for i in 0 ..< EFS {T[i]=D[i+1]} - var u=BIG.fromBytes(T) - for i in 0 ..< EFS {T[i]=D[i+EFS+1]} - var v=BIG.fromBytes(T) - - let su=D[0]&1 - let sv=(D[0]>>1)&1 - let W=map(u,Int(su)) - let P=map(v,Int(sv)) - P.add(W) - u=P.getX() - v=P.getY() - D[0]=0x04 - u.toBytes(&T); - for i in 0 ..< EFS {D[i+1]=T[i]} - v.toBytes(&T) - for i in 0 ..< EFS {D[i+EFS+1]=T[i]} - - return 0 - } - // R=R1+R2 in group G1 - static public func RECOMBINE_G1(_ R1:[UInt8],_ R2:[UInt8],_ R:inout [UInt8]) -> Int - { - let P=ECP.fromBytes(R1) - let Q=ECP.fromBytes(R2) - - if P.is_infinity() || Q.is_infinity() {return INVALID_POINT} - - P.add(Q) - - P.toBytes(&R) - return 0; - } - // W=W1+W2 in group G2 - static public func RECOMBINE_G2(_ W1:[UInt8],_ W2:[UInt8],_ W:inout [UInt8]) -> Int - { - let P=ECP2.fromBytes(W1) - let Q=ECP2.fromBytes(W2) - - if P.is_infinity() || Q.is_infinity() {return INVALID_POINT} - - P.add(Q) - - P.toBytes(&W) - return 0 - } - // create random secret S - static public func RANDOM_GENERATE(_ rng:RAND,_ S:inout [UInt8]) -> Int - { - let r=BIG(ROM.CURVE_Order) - let s=BIG.randomnum(r,rng) - if ROM.AES_S>0 - { - s.mod2m(2*ROM.AES_S) - } - s.toBytes(&S); - return 0; - } - // Extract PIN from TOKEN for identity CID - static public func EXTRACT_PIN(_ sha:Int,_ CID:[UInt8],_ pin:Int32,_ TOKEN:inout [UInt8]) -> Int - { - let P=ECP.fromBytes(TOKEN) - if P.is_infinity() {return INVALID_POINT} - let h=MPIN.hashit(sha,0,CID) - var R=MPIN.mapit(h) - - R=R.pinmul(pin%MAXPIN,MPIN.PBLEN) - P.sub(R) - - P.toBytes(&TOKEN) - - return 0 - } - // Implement step 2 on client side of MPin protocol - static public func CLIENT_2(_ X:[UInt8],_ Y:[UInt8],_ SEC:inout [UInt8]) -> Int - { - let r=BIG(ROM.CURVE_Order) - var P=ECP.fromBytes(SEC) - if P.is_infinity() {return INVALID_POINT} - - let px=BIG.fromBytes(X) - let py=BIG.fromBytes(Y) - px.add(py) - px.mod(r) - // px.rsub(r) - - P=PAIR.G1mul(P,px) - P.neg() - P.toBytes(&SEC); - // PAIR.G1mul(P,px).toBytes(&SEC) - return 0 - } - - // Implement step 1 on client side of MPin protocol - static public func CLIENT_1(_ sha:Int,_ date:Int32,_ CLIENT_ID:[UInt8],_ rng:RAND?,_ X:inout [UInt8],_ pin:Int32,_ TOKEN:[UInt8],_ SEC:inout [UInt8],_ xID:inout [UInt8]?,_ xCID:inout [UInt8]?,_ PERMIT:[UInt8]) -> Int - { - let r=BIG(ROM.CURVE_Order) - // let q=BIG(ROM.Modulus) - var x:BIG - if rng != nil - { - x=BIG.randomnum(r,rng!) - if ROM.AES_S>0 - { - x.mod2m(2*ROM.AES_S) - } - x.toBytes(&X); - } - else - { - x=BIG.fromBytes(X); - } - // var t=[UInt8](count:EFS,repeatedValue:0) - - var h=MPIN.hashit(sha,0,CLIENT_ID) - var P=mapit(h); - - let T=ECP.fromBytes(TOKEN); - if T.is_infinity() {return INVALID_POINT} - - var W=P.pinmul(pin%MPIN.MAXPIN,MPIN.PBLEN) - T.add(W) - if date != 0 - { - W=ECP.fromBytes(PERMIT) - if W.is_infinity() {return INVALID_POINT} - T.add(W); - h=MPIN.hashit(sha,date,h) - W=MPIN.mapit(h); - if xID != nil - { - P=PAIR.G1mul(P,x) - P.toBytes(&xID!) - W=PAIR.G1mul(W,x) - P.add(W) - } - else - { - P.add(W); - P=PAIR.G1mul(P,x); - } - if xCID != nil {P.toBytes(&xCID!)} - } - else - { - if xID != nil - { - P=PAIR.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 - static public func GET_SERVER_SECRET(_ S:[UInt8],_ SST:inout [UInt8]) -> Int - { - var Q=ECP2(FP2(BIG(ROM.CURVE_Pxa),BIG(ROM.CURVE_Pxb)),FP2(BIG(ROM.CURVE_Pya),BIG(ROM.CURVE_Pyb))) - - let s=BIG.fromBytes(S) - Q=PAIR.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 - - static public func GET_G1_MULTIPLE(_ rng:RAND?,_ type:Int,_ X:inout [UInt8],_ G:[UInt8],_ W:inout [UInt8]) -> Int - { - var x:BIG - let r=BIG(ROM.CURVE_Order) - if rng != nil - { - x=BIG.randomnum(r,rng!) - if ROM.AES_S>0 - { - x.mod2m(2*ROM.AES_S) - } - x.toBytes(&X) - } - else - { - x=BIG.fromBytes(X); - } - var P:ECP - if type==0 - { - P=ECP.fromBytes(G) - if P.is_infinity() {return INVALID_POINT} - } - else - {P=MPIN.mapit(G)} - - PAIR.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 - static public func GET_CLIENT_SECRET(_ S:inout [UInt8],_ CID:[UInt8],_ CST:inout [UInt8]) -> Int - { - return GET_G1_MULTIPLE(nil,1,&S,CID,&CST) - } - // Time Permit CTT=S*(date|H(CID)) where S is master secret - static public func GET_CLIENT_PERMIT(_ sha:Int,_ date:Int32,_ S:[UInt8],_ CID:[UInt8],_ CTT:inout [UInt8]) -> Int - { - let h=MPIN.hashit(sha,date,CID) - let P=MPIN.mapit(h) - - let s=BIG.fromBytes(S) - PAIR.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 - static public func SERVER_1(_ sha:Int,_ date:Int32,_ CID:[UInt8],_ HID:inout [UInt8],_ HTID:inout [UInt8]) - { - var h=MPIN.hashit(sha,0,CID) - let P=MPIN.mapit(h) - - P.toBytes(&HID) - if date != 0 - { - // if HID != nil {P.toBytes(&HID!)} - h=hashit(sha,date,h) - let R=MPIN.mapit(h) - P.add(R) - P.toBytes(&HTID) - } - //else {P.toBytes(&HID!)} - } - // Implement step 2 of MPin protocol on server side - static public func SERVER_2(_ date:Int32,_ HID:[UInt8]?,_ HTID:[UInt8]?,_ Y:[UInt8],_ SST:[UInt8],_ xID:[UInt8]?,_ xCID:[UInt8]?,_ mSEC:[UInt8],_ E:inout [UInt8]?,_ F:inout [UInt8]?) -> Int - { - // _=BIG(ROM.Modulus); - let Q=ECP2(FP2(BIG(ROM.CURVE_Pxa),BIG(ROM.CURVE_Pxb)),FP2(BIG(ROM.CURVE_Pya),BIG(ROM.CURVE_Pyb))) - let sQ=ECP2.fromBytes(SST) - if sQ.is_infinity() {return 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 INVALID_POINT} - - let y=BIG.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 INVALID_POINT} - - P=PAIR.G1mul(P,y) - P.add(R) - R=ECP.fromBytes(mSEC) - if R.is_infinity() {return MPIN.INVALID_POINT} - - - var g=PAIR.ate2(Q,R,sQ,P) - g=PAIR.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=PAIR.G1mul(P,y); - P.add(R); - } - g=PAIR.ate(Q,P); - g=PAIR.fexp(g); - g.toBytes(&F!); - } - return MPIN.BAD_PIN; - } - - return 0 - } - // Pollards kangaroos used to return PIN error - static public func KANGAROO(_ E:[UInt8],_ F:[UInt8]) -> Int - { - let ge=FP12.fromBytes(E) - let gf=FP12.fromBytes(F) - var distance=[Int](); - let t=FP12(gf); - var table=[FP12]() - - var s:Int=1 - for _ in 0 ..< Int(TS) - { - distance.append(s) - table.append(FP12(t)) - s*=2 - t.usqr() - - } - t.one() - var dn:Int=0 - for _ in 0 ..< TRAP - { - let i=Int(t.geta().geta().getA().lastbits(8))%TS - t.mul(table[i]) - dn+=distance[i] - } - gf.copy(t); gf.conj() - var steps=0; var dm:Int=0 - var res=0; - while (dm-dn<Int(MAXPIN)) - { - steps += 1; - if steps>4*TRAP {break} - let i=Int(ge.geta().geta().getA().lastbits(8))%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*TRAP || dm-dn>=Int(MAXPIN) {res=0 } // Trap Failed - probable invalid token - return res - } - // Functions to support M-Pin Full - - static public func PRECOMPUTE(_ TOKEN:[UInt8],_ CID:[UInt8],_ G1:inout [UInt8],_ G2:inout [UInt8]) -> Int - { - let T=ECP.fromBytes(TOKEN); - if T.is_infinity() {return INVALID_POINT} - - let P=MPIN.mapit(CID) - - let Q=ECP2(FP2(BIG(ROM.CURVE_Pxa),BIG(ROM.CURVE_Pxb)),FP2(BIG(ROM.CURVE_Pya),BIG(ROM.CURVE_Pyb))) - - var g=PAIR.ate(Q,T) - g=PAIR.fexp(g) - g.toBytes(&G1) - - g=PAIR.ate(Q,P) - g=PAIR.fexp(g) - g.toBytes(&G2) - - return 0 - } - - static public func HASH_ALL(_ sha:Int,_ HID:[UInt8],_ xID:[UInt8]?,_ xCID:[UInt8]?,_ SEC:[UInt8],_ Y:[UInt8],_ R:[UInt8],_ W:[UInt8] ) -> [UInt8] - { - var T=[UInt8](repeating: 0,count: 10*EFS+4) - var tlen=0 - - for i in 0 ..< HID.count {T[i]=HID[i]} - tlen+=HID.count - if xCID != nil { - for i in 0 ..< xCID!.count {T[i+tlen]=xCID![i]} - tlen+=xCID!.count - } else { - for i in 0 ..< xID!.count {T[i+tlen]=xID![i]} - tlen+=xID!.count - } - for i in 0 ..< SEC.count {T[i+tlen]=SEC[i]} - tlen+=SEC.count; - for i in 0 ..< Y.count {T[i+tlen]=Y[i]} - tlen+=Y.count; - for i in 0 ..< R.count {T[i+tlen]=R[i]} - tlen+=R.count; - for i in 0 ..< W.count {T[i+tlen]=W[i]} - tlen+=W.count; - - return hashit(sha,0,T); - } - - // calculate common key on client side - // wCID = w.(A+AT) - static public func CLIENT_KEY(_ sha:Int,_ G1:[UInt8],_ G2:[UInt8],_ pin:Int32,_ R:[UInt8],_ X:[UInt8],_ H:[UInt8],_ wCID:[UInt8],_ CK:inout [UInt8]) -> Int - { - let g1=FP12.fromBytes(G1) - let g2=FP12.fromBytes(G2) - let z=BIG.fromBytes(R) - let x=BIG.fromBytes(X) - let h=BIG.fromBytes(H) - - var W=ECP.fromBytes(wCID) - if W.is_infinity() {return INVALID_POINT} - - W=PAIR.G1mul(W,x) - - let f=FP2(BIG(ROM.CURVE_Fra),BIG(ROM.CURVE_Frb)) - let r=BIG(ROM.CURVE_Order) - let q=BIG(ROM.Modulus) - - z.add(h) // new - z.mod(r) - - let m=BIG(q) - m.mod(r) - - let a=BIG(z) - a.mod(m) - - let b=BIG(z) - b.div(m); - - g2.pinpow(pin,PBLEN); - g1.mul(g2); - - var c=g1.trace() - g2.copy(g1) - g2.frob(f) - let cp=g2.trace() - g1.conj() - g2.mul(g1) - let cpm1=g2.trace() - g2.mul(g1) - let cpm2=g2.trace() - - c=c.xtr_pow2(cp,cpm1,cpm2,a,b) - - let t=mpin_hash(sha,c,W) - - for i in 0 ..< PAS {CK[i]=t[i]} - - return 0 - } - // calculate common key on server side - // Z=r.A - no time permits involved - - static public func SERVER_KEY(_ sha:Int,_ Z:[UInt8],_ SST:[UInt8],_ W:[UInt8],_ H:[UInt8],_ HID:[UInt8],_ xID:[UInt8],_ xCID:[UInt8]?,_ SK:inout [UInt8]) -> Int - { - // var t=[UInt8](count:EFS,repeatedValue:0) - - let sQ=ECP2.fromBytes(SST) - if sQ.is_infinity() {return INVALID_POINT} - let R=ECP.fromBytes(Z) - if R.is_infinity() {return INVALID_POINT} - var A=ECP.fromBytes(HID) - if A.is_infinity() {return INVALID_POINT} - - var U:ECP - if xCID != nil - {U=ECP.fromBytes(xCID!)} - else - {U=ECP.fromBytes(xID)} - - if U.is_infinity() {return INVALID_POINT} - - let w=BIG.fromBytes(W) - let h=BIG.fromBytes(H) - A=PAIR.G1mul(A,h) - R.add(A) - - U=PAIR.G1mul(U,w) - var g=PAIR.ate(sQ,R) - g=PAIR.fexp(g) - - let c=g.trace() - - let t=mpin_hash(sha,c,U) - - for i in 0 ..< PAS {SK[i]=t[i]} - - return 0 - } - - // return time since epoch - static public func GET_TIME() -> Int32 - { - let date=Date() - return (Int32(date.timeIntervalSince1970)) - } - - // Generate Y = H(epoch, xCID/xID) - static public func GET_Y(_ sha:Int,_ TimeValue:Int32,_ xCID:[UInt8],_ Y:inout [UInt8]) - { - let h = MPIN.hashit(sha,TimeValue,xCID) - let y = BIG.fromBytes(h) - let q=BIG(ROM.CURVE_Order) - y.mod(q) - if ROM.AES_S>0 - { - y.mod2m(2*ROM.AES_S) - } - y.toBytes(&Y) - } - // One pass MPIN Client - static public func CLIENT(_ sha:Int,_ date:Int32,_ CLIENT_ID:[UInt8],_ RNG:RAND?,_ X:inout [UInt8],_ pin:Int32,_ TOKEN:[UInt8],_ SEC:inout [UInt8],_ xID:inout [UInt8]?,_ xCID:inout [UInt8]?,_ PERMIT:[UInt8],_ TimeValue:Int32,_ Y:inout [UInt8]) -> Int - { - var rtn=0 - - rtn = MPIN.CLIENT_1(sha,date,CLIENT_ID,RNG,&X,pin,TOKEN,&SEC,&xID,&xCID,PERMIT) - - if rtn != 0 {return rtn} - - if date==0 {MPIN.GET_Y(sha,TimeValue,xID!,&Y)} - else {MPIN.GET_Y(sha,TimeValue,xCID!,&Y)} - - rtn = MPIN.CLIENT_2(X,Y,&SEC) - if (rtn != 0) {return rtn} - - return 0 - } - // One pass MPIN Server - static public func SERVER(_ sha:Int,_ date:Int32,_ HID:inout [UInt8],_ HTID:inout [UInt8]?,_ Y:inout [UInt8],_ SST:[UInt8],_ xID:[UInt8]?,_ xCID:[UInt8],_ SEC:[UInt8],_ E:inout [UInt8]?,_ F:inout [UInt8]?,_ CID:[UInt8],_ TimeValue:Int32) -> Int - { - var rtn=0 - - var pID:[UInt8] - if date == 0 - {pID = xID!} - else - {pID = xCID} - - SERVER_1(sha,date,CID,&HID,&HTID!); - - GET_Y(sha,TimeValue,pID,&Y); - - rtn = SERVER_2(date,HID,HTID!,Y,SST,xID,xCID,SEC,&E,&F); - if rtn != 0 {return rtn} - - return 0 - } - - static public func printBinary(_ array: [UInt8]) - { - for i in 0 ..< array.count - { - let h=String(format:"%02x",array[i]) - print("\(h)", terminator: "") - } - print(" "); - } -} - -
