You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by br...@apache.org on 2019/01/15 15:19:45 UTC

[40/51] [partial] incubator-milagro-crypto git commit: update code

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/go/MPIN.go
----------------------------------------------------------------------
diff --git a/version22/go/MPIN.go b/version22/go/MPIN.go
deleted file mode 100644
index 43b5f32..0000000
--- a/version22/go/MPIN.go
+++ /dev/null
@@ -1,769 +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 main
-
-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
-const MPIN_SHA256 int=32
-const MPIN_SHA384 int=48
-const MPIN_SHA512 int=64
-
-/* 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) */
-
-const MPIN_HASH_TYPE int=MPIN_SHA256
-
-func mpin_hash(sha int,c *FP4,U *ECP) []byte {
-	var w [MPIN_EFS]byte
-	var t [6*MPIN_EFS]byte
-	var h []byte
-
-	c.geta().getA().toBytes(w[:]); for i:=0;i<MPIN_EFS;i++ {t[i]=w[i]}
-	c.geta().getB().toBytes(w[:]); for i:=MPIN_EFS;i<2*MPIN_EFS;i++ {t[i]=w[i-MPIN_EFS]}
-	c.getb().getA().toBytes(w[:]); for i:=2*MPIN_EFS;i<3*MPIN_EFS;i++ {t[i]=w[i-2*MPIN_EFS]}
-	c.getb().getB().toBytes(w[:]); for i:=3*MPIN_EFS;i<4*MPIN_EFS;i++ {t[i]=w[i-3*MPIN_EFS]}
-
-	U.getX().toBytes(w[:]); for i:=4*MPIN_EFS;i<5*MPIN_EFS;i++ {t[i]=w[i-4*MPIN_EFS]}
-	U.getY().toBytes(w[:]); for i:=5*MPIN_EFS;i<6*MPIN_EFS;i++ {t[i]=w[i-5*MPIN_EFS]}
-
-	if sha==MPIN_SHA256 {
-		H:=NewHASH256()
-		H.Process_array(t[:])
-		h=H.Hash()
-	}
-	if sha==MPIN_SHA384 {
-		H:=NewHASH384()
-		H.Process_array(t[:])
-		h=H.Hash()
-	}
-	if sha==MPIN_SHA512 {
-		H:=NewHASH512()
-		H.Process_array(t[:])
-		h=H.Hash()
-	}
-	if h==nil {return nil}
-	R:=make([]byte,MPIN_PAS)
-	for i:=0;i<MPIN_PAS;i++ {R[i]=h[i]}
-	return R
-}
-
-/* Hash number (optional) and string to coordinate on curve */
-
-func mhashit(sha int,n int32,ID []byte) []byte {
-	var R []byte
-	if sha==MPIN_SHA256 {
-		H:=NewHASH256()
-		if n!=0 {H.Process_num(n)}
-		H.Process_array(ID)
-		R=H.Hash()
-	}
-	if sha==MPIN_SHA384 {
-		H:=NewHASH384()
-		if n!=0 {H.Process_num(n)}
-		H.Process_array(ID)
-		R=H.Hash()
-	}
-	if sha==MPIN_SHA512 {
-		H:=NewHASH512()
-		if n!=0 {H.Process_num(n)}
-		H.Process_array(ID)
-		R=H.Hash()
-	}
-	if R==nil {return nil}
-	const RM int=int(MODBYTES)
-	var W [RM]byte
-	if sha>RM {
-		for i:=0;i<RM;i++ {W[i]=R[i]}
-	} else {
-		for i:=0;i<sha;i++ {W[i]=R[i]}	
-		for i:=sha;i<RM;i++ {W[i]=0}
-	}
-
-	return W[:]
-}
-
-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()
-	}
-	if CURVE_PAIRING_TYPE!=BN_CURVE {
-		c:=NewBIGints(CURVE_Cof)
-		P=P.mul(c)
-	}	
-	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(sha int,ID []byte) []byte {
-	return mhashit(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 */
-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()); /*if (su<0) su=-su;*/ su%=2
-		
-	W:=emap(u,su)
-	P.sub(W)
-	sv:=P.getS()
-	rn:=unmap(v,P)
-	m:=int(rng.GetByte()); /*if (m<0) m=-m;*/ 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)
-	if AES_S>0 {
-		s.mod2m(2*AES_S)
-	}		
-	s.toBytes(S)
-	return 0
-}
-
-/* Extract PIN from TOKEN for identity CID */
-func MPIN_EXTRACT_PIN(sha int,CID []byte,pin int,TOKEN []byte) int {
-	P:=ECP_fromBytes(TOKEN)
-	if P.is_infinity() {return MPIN_INVALID_POINT}
-	h:=mhashit(sha,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)
-
-	P=G1mul(P,px)
-	P.neg()
-	P.toBytes(SEC)
-	//G1mul(P,px).toBytes(SEC)
-	return 0
-}
-
-/* Implement step 1 on client side of MPin protocol */
-func MPIN_CLIENT_1(sha int,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)
-		if AES_S>0 {
-			x.mod2m(2*AES_S)
-		}
-		x.toBytes(X)
-	} else {
-		x=fromBytes(X)
-	}
-
-	h:=mhashit(sha,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=mhashit(sha,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)
-		if AES_S>0 {
-			x.mod2m(2*AES_S)
-		}
-		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(sha,date int,S []byte,CID []byte,CTT []byte) int {
-	h:=mhashit(sha,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(sha int,date int,CID []byte,HID []byte,HTID []byte) {
-	h:=mhashit(sha,0,CID)
-	P:=mapit(h)
-	
-	P.toBytes(HID);
-	if date!=0 {
-	//	if HID!=nil {P.toBytes(HID)}
-		h=mhashit(sha,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(20)%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(20)%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
-}
-
-/* Hash the M-Pin transcript - new */
-
-func MPIN_HASH_ALL(sha int,HID []byte,xID []byte,xCID []byte,SEC []byte,Y []byte,R []byte,W []byte) []byte {
-	tlen:=0
-	var T [10*int(MODBYTES)+4]byte
-
-	for i:=0;i<len(HID);i++ {T[i]=HID[i]}
-	tlen+=len(HID)
-	if xCID!=nil {
-		for i:=0;i<len(xCID);i++ {T[i+tlen]=xCID[i]}
-		tlen+=len(xCID)
-	} else {
-		for i:=0;i<len(xID);i++ {T[i+tlen]=xID[i]}
-		tlen+=len(xID)
-	}	
-	for i:=0;i<len(SEC);i++ {T[i+tlen]=SEC[i]}
-	tlen+=len(SEC)		
-	for i:=0;i<len(Y);i++ {T[i+tlen]=Y[i]}
-	tlen+=len(Y)
-	for i:=0;i<len(R);i++ {T[i+tlen]=R[i]}
-	tlen+=len(R)		
-	for i:=0;i<len(W);i++ {T[i+tlen]=W[i]}
-	tlen+=len(W)	
-
-	return mhashit(sha,0,T[:])
-}
-
-/* calculate common key on client side */
-/* wCID = w.(A+AT) */
-func MPIN_CLIENT_KEY(sha int,G1 []byte,G2 []byte,pin int,R []byte,X []byte,H []byte,wCID []byte,CK []byte) int {
-
-	g1:=FP12_fromBytes(G1)
-	g2:=FP12_fromBytes(G2)
-	z:=fromBytes(R)
-	x:=fromBytes(X)
-	h:=fromBytes(H)
-
-	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)
-
-	z.add(h);	//new
-	z.mod(r);
-
-	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)
-
-	t:=mpin_hash(sha,c,W);
-
-	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(sha int,Z []byte,SST []byte,W []byte,H []byte,HID []byte,xID []byte,xCID []byte,SK []byte) int {
-	sQ:=ECP2_fromBytes(SST)
-	if sQ.is_infinity() {return MPIN_INVALID_POINT} 
-	R:=ECP_fromBytes(Z)
-	if R.is_infinity() {return MPIN_INVALID_POINT} 
-	A:=ECP_fromBytes(HID)
-	if A.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)
-	h:=fromBytes(H)
-	A=G1mul(A,h)	// new
-	R.add(A)
-
-	U=G1mul(U,w)
-	g:=ate(sQ,R)
-	g=fexp(g)
-
-	c:=g.trace()
-
-	t:=mpin_hash(sha,c,U)
-
-	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(sha int,TimeValue int,xCID []byte,Y []byte) {
-	h:= mhashit(sha,int32(TimeValue),xCID)
-	y:= fromBytes(h)
-	q:=NewBIGints(CURVE_Order)
-	y.mod(q)
-	if AES_S>0 {
-		y.mod2m(2*AES_S)
-	}
-	y.toBytes(Y)
-}
-        
-/* One pass MPIN Client */
-func MPIN_CLIENT(sha int,date int,CLIENT_ID []byte,RNG *RAND,X []byte,pin int,TOKEN []byte,SEC []byte,xID []byte,xCID []byte,PERMIT []byte,TimeValue int,Y []byte) int {
-	rtn:=0
-        
-	var pID []byte
-	if date == 0 {
-		pID = xID
-	} else {pID = xCID}
-          
-	rtn = MPIN_CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT)
-	if rtn != 0 {return rtn}
-        
-	MPIN_GET_Y(sha,TimeValue,pID,Y)
-        
-	rtn = MPIN_CLIENT_2(X,Y,SEC)
-	if rtn != 0 {return rtn}
-        
-	return 0
-}
-
-/* One pass MPIN Server */
-func MPIN_SERVER(sha int,date int,HID []byte,HTID []byte,Y []byte,SST []byte,xID []byte,xCID []byte,SEC []byte,E []byte,F []byte,CID []byte,TimeValue int) int {
-	rtn:=0
-        
-	var pID []byte
-	if date == 0 {
-		pID = xID
-	} else {pID = xCID}
-       
-	MPIN_SERVER_1(sha,date,CID,HID,HTID)
-	MPIN_GET_Y(sha,TimeValue,pID,Y);
-    
-	rtn = MPIN_SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F)
-	if rtn != 0 {return rtn}
-        
-	return 0
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/go/PAIR.go
----------------------------------------------------------------------
diff --git a/version22/go/PAIR.go b/version22/go/PAIR.go
deleted file mode 100644
index 89c80ce..0000000
--- a/version22/go/PAIR.go
+++ /dev/null
@@ -1,641 +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.
-*/
-
-/* MiotCL BN Curve Pairing functions */
-
-package main
-
-//import "fmt"
-
-/* Line function */
-func line(A *ECP2,B *ECP2,Qx *FP,Qy *FP) *FP12 {
-	P:=NewECP2()
-
-	P.copy(A);
-	ZZ:=NewFP2copy(P.getz())
-	ZZ.sqr()
-	var D int
-	if A==B {
-		D=A.dbl() 
-	} else {D=A.add(B)}
-
-	if D<0 {return NewFP12int(1)}
-
-	Z3:=NewFP2copy(A.getz())
-
-	var a *FP4
-	var b *FP4
-	c:=NewFP4int(0)
-
-	if (D==0) { /* Addition */
-		X:=NewFP2copy(B.getx())
-		Y:=NewFP2copy(B.gety())
-		T:=NewFP2copy(P.getz()) 
-		T.mul(Y)
-		ZZ.mul(T)
-
-		NY:=NewFP2copy(P.gety()); NY.neg()
-		ZZ.add(NY)
-		Z3.pmul(Qy)
-		T.mul(P.getx());
-		X.mul(NY);
-		T.add(X);
-		a=NewFP4fp2s(Z3,T)
-		ZZ.neg();
-		ZZ.pmul(Qx)
-		b=NewFP4fp2(ZZ)
-	} else { /* Doubling */
-		X:=NewFP2copy(P.getx())
-		Y:=NewFP2copy(P.gety())
-		T:=NewFP2copy(P.getx())
-		T.sqr()
-		T.imul(3)
-
-		Y.sqr()
-		Y.add(Y)
-		Z3.mul(ZZ)
-		Z3.pmul(Qy)
-
-		X.mul(T)
-		X.sub(Y)
-		a=NewFP4fp2s(Z3,X)
-		T.neg()
-		ZZ.mul(T)
-		ZZ.pmul(Qx)
-		b=NewFP4fp2(ZZ)
-	}
-	return NewFP12fp4s(a,b,c)
-}
-
-/* Optimal R-ate pairing */
-func ate(P *ECP2,Q *ECP) *FP12 {
-	f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-	x:=NewBIGints(CURVE_Bnx)
-	n:=NewBIGcopy(x)
-	K:=NewECP2()
-	var lv *FP12
-	
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		n.pmul(6); n.dec(2)
-	} else {n.copy(x)}
-	
-	n.norm()
-	P.affine()
-	Q.affine()
-	Qx:=NewFPcopy(Q.getx())
-	Qy:=NewFPcopy(Q.gety())
-
-	A:=NewECP2()
-	r:=NewFP12int(1)
-
-	A.copy(P)
-	nb:=n.nbits()
-
-	for i:=nb-2;i>=1;i-- {
-		lv=line(A,A,Qx,Qy)
-		r.smul(lv)
-		if n.bit(i)==1 {
-	
-			lv=line(A,P,Qx,Qy)
-			
-			r.smul(lv)
-		}		
-		r.sqr()
-	}
-
-	lv=line(A,A,Qx,Qy)
-	r.smul(lv)
-
-	if n.parity()==1 {
-		lv=line(A,P,Qx,Qy)
-		r.smul(lv)
-	}
-
-/* R-ate fixup required for BN curves */
-
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		r.conj()
-		K.copy(P)
-		K.frob(f)
-		A.neg()
-		lv=line(A,K,Qx,Qy)
-		r.smul(lv)
-		K.frob(f)
-		K.neg()
-		lv=line(A,K,Qx,Qy)
-		r.smul(lv)
-	}
-
-	return r
-}
-
-/* Optimal R-ate double pairing e(P,Q).e(R,S) */
-func ate2(P *ECP2,Q *ECP,R *ECP2,S *ECP) *FP12 {
-	f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-	x:=NewBIGints(CURVE_Bnx)
-	n:=NewBIGcopy(x)
-	K:=NewECP2()
-	var lv *FP12
-
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		n.pmul(6); n.dec(2)
-	} else {n.copy(x)}
-	
-	n.norm()
-	P.affine()
-	Q.affine()
-	R.affine()
-	S.affine()
-
-	Qx:=NewFPcopy(Q.getx())
-	Qy:=NewFPcopy(Q.gety())
-	Sx:=NewFPcopy(S.getx())
-	Sy:=NewFPcopy(S.gety())
-
-	A:=NewECP2()
-	B:=NewECP2()
-	r:=NewFP12int(1)
-
-	A.copy(P)
-	B.copy(R)
-	nb:=n.nbits()
-
-	for i:=nb-2;i>=1;i-- {
-		lv=line(A,A,Qx,Qy)
-		r.smul(lv)
-		lv=line(B,B,Sx,Sy)
-		r.smul(lv)
-
-		if n.bit(i)==1 {
-			lv=line(A,P,Qx,Qy)
-			r.smul(lv)
-			lv=line(B,R,Sx,Sy)
-			r.smul(lv)
-		}
-		r.sqr()
-	}
-
-	lv=line(A,A,Qx,Qy)
-	r.smul(lv)
-	lv=line(B,B,Sx,Sy)
-	r.smul(lv)
-	if n.parity()==1 {
-		lv=line(A,P,Qx,Qy)
-		r.smul(lv)
-		lv=line(B,R,Sx,Sy)
-		r.smul(lv)
-	}
-
-/* R-ate fixup */
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		r.conj()
-		K.copy(P)
-		K.frob(f)
-		A.neg()
-		lv=line(A,K,Qx,Qy)
-		r.smul(lv)
-		K.frob(f)
-		K.neg()
-		lv=line(A,K,Qx,Qy)
-		r.smul(lv)
-
-		K.copy(R)
-		K.frob(f)
-		B.neg()
-		lv=line(B,K,Sx,Sy)
-		r.smul(lv)
-		K.frob(f)
-		K.neg()
-		lv=line(B,K,Sx,Sy)
-		r.smul(lv)
-	}
-
-	return r
-}
-
-/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
-func fexp(m *FP12) *FP12 {
-	f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-	x:=NewBIGints(CURVE_Bnx)
-	r:=NewFP12copy(m)
-		
-/* Easy part of final exp */
-	lv:=NewFP12copy(r)
-	lv.inverse()
-	r.conj()
-
-	r.mul(lv)
-	lv.copy(r)
-	r.frob(f)
-	r.frob(f)
-	r.mul(lv)
-/* Hard part of final exp */
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		lv.copy(r)
-		lv.frob(f)
-		x0:=NewFP12copy(lv)
-		x0.frob(f)
-		lv.mul(r)
-		x0.mul(lv)
-		x0.frob(f)
-		x1:=NewFP12copy(r)
-		x1.conj()
-		x4:=r.pow(x)
-
-		x3:=NewFP12copy(x4)
-		x3.frob(f)
-
-		x2:=x4.pow(x)
-
-		x5:=NewFP12copy(x2); x5.conj()
-		lv=x2.pow(x)
-
-		x2.frob(f)
-		r.copy(x2); r.conj()
-
-		x4.mul(r)
-		x2.frob(f)
-
-		r.copy(lv)
-		r.frob(f)
-		lv.mul(r)
-
-		lv.usqr()
-		lv.mul(x4)
-		lv.mul(x5)
-		r.copy(x3)
-		r.mul(x5)
-		r.mul(lv)
-		lv.mul(x2)
-		r.usqr()
-		r.mul(lv)
-		r.usqr()
-		lv.copy(r)
-		lv.mul(x1)
-		r.mul(x0)
-		lv.usqr()
-		r.mul(lv)
-		r.reduce()
-	} else {
-		
-// Ghamman & Fouotsa Method
-		y0:=NewFP12copy(r); y0.usqr()
-		y1:=y0.pow(x)
-		x.fshr(1); y2:=y1.pow(x); x.fshl(1)
-		y3:=NewFP12copy(r); y3.conj()
-		y1.mul(y3)
-
-		y1.conj()
-		y1.mul(y2)
-
-		y2=y1.pow(x)
-
-		y3=y2.pow(x)
-		y1.conj()
-		y3.mul(y1)
-
-		y1.conj();
-		y1.frob(f); y1.frob(f); y1.frob(f)
-		y2.frob(f); y2.frob(f)
-		y1.mul(y2)
-
-		y2=y3.pow(x)
-		y2.mul(y0)
-		y2.mul(r)
-
-		y1.mul(y2)
-		y2.copy(y3); y2.frob(f)
-		y1.mul(y2)
-		r.copy(y1)
-		r.reduce()
-
-
-/*
-		x0:=NewFP12copy(r)
-		x1:=NewFP12copy(r)
-		lv.copy(r); lv.frob(f)
-		x3:=NewFP12copy(lv); x3.conj(); x1.mul(x3)
-		lv.frob(f); lv.frob(f)
-		x1.mul(lv)
-
-		r.copy(r.pow(x))  //r=r.pow(x);
-		x3.copy(r); x3.conj(); x1.mul(x3)
-		lv.copy(r); lv.frob(f)
-		x0.mul(lv)
-		lv.frob(f)
-		x1.mul(lv)
-		lv.frob(f)
-		x3.copy(lv); x3.conj(); x0.mul(x3)
-
-		r.copy(r.pow(x))
-		x0.mul(r)
-		lv.copy(r); lv.frob(f); lv.frob(f)
-		x3.copy(lv); x3.conj(); x0.mul(x3)
-		lv.frob(f)
-		x1.mul(lv)
-
-		r.copy(r.pow(x))
-		lv.copy(r); lv.frob(f)
-		x3.copy(lv); x3.conj(); x0.mul(x3)
-		lv.frob(f)
-		x1.mul(lv)
-
-		r.copy(r.pow(x))
-		x3.copy(r); x3.conj(); x0.mul(x3)
-		lv.copy(r); lv.frob(f)
-		x1.mul(lv)
-
-		r.copy(r.pow(x))
-		x1.mul(r)
-
-		x0.usqr()
-		x0.mul(x1)
-		r.copy(x0)
-		r.reduce() */
-	}
-	return r
-}
-
-/* GLV method */
-func glv(e *BIG) []*BIG {
-	var u []*BIG
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		t:=NewBIGint(0)
-		q:=NewBIGints(CURVE_Order)
-		var v []*BIG
-
-		for i:=0;i<2;i++ {
-			t.copy(NewBIGints(CURVE_W[i]))  // why not just t=new BIG(ROM.CURVE_W[i]); 
-			d:=mul(t,e)
-			v=append(v,NewBIGcopy(d.div(q)))
-			u=append(u,NewBIGint(0))
-		}
-		u[0].copy(e)
-		for i:=0;i<2;i++ {
-			for j:=0;j<2;j++ {
-				t.copy(NewBIGints(CURVE_SB[j][i]))
-				t.copy(modmul(v[j],t,q))
-				u[i].add(q)
-				u[i].sub(t)
-				u[i].mod(q)
-			}
-		}
-	} else {
-		q:=NewBIGints(CURVE_Order)
-		x:=NewBIGints(CURVE_Bnx)
-		x2:=smul(x,x)
-		u=append(u,NewBIGcopy(e))
-		u[0].mod(x2)
-		u=append(u,NewBIGcopy(e))
-		u[1].div(x2)
-		u[1].rsub(q)
-	}
-	return u
-}
-
-/* Galbraith & Scott Method */
-func gs(e *BIG) []*BIG {
-	var u []*BIG
-	if CURVE_PAIRING_TYPE == BN_CURVE {
-		t:=NewBIGint(0)
-		q:=NewBIGints(CURVE_Order)
-
-		var v []*BIG
-		for i:=0;i<4;i++ {
-			t.copy(NewBIGints(CURVE_WB[i]))
-			d:=mul(t,e)
-			v=append(v,NewBIGcopy(d.div(q)))
-			u=append(u,NewBIGint(0))
-		}
-		u[0].copy(e)
-		for i:=0;i<4;i++ {
-			for j:=0;j<4;j++ {
-				t.copy(NewBIGints(CURVE_BB[j][i]))
-				t.copy(modmul(v[j],t,q))
-				u[i].add(q)
-				u[i].sub(t)
-				u[i].mod(q)
-			}
-		}
-	} else {
-		x:=NewBIGints(CURVE_Bnx)
-		w:=NewBIGcopy(e)
-		for i:=0;i<4;i++ {
-			u=append(u,NewBIGcopy(w))
-			u[i].mod(x)
-			w.div(x)
-		}
-	}
-	return u
-}	
-
-/* Multiply P by e in group G1 */
-func G1mul(P *ECP,e *BIG) *ECP {
-	var R *ECP
-	if (USE_GLV) {
-		P.affine()
-		R=NewECP()
-		R.copy(P)
-		Q:=NewECP()
-		Q.copy(P)
-		q:=NewBIGints(CURVE_Order);
-		cru:=NewFPbig(NewBIGints(CURVE_Cru))
-		t:=NewBIGint(0)
-		u:=glv(e)
-		Q.getx().mul(cru)
-
-		np:=u[0].nbits()
-		t.copy(modneg(u[0],q))
-		nn:=t.nbits()
-		if nn<np {
-			u[0].copy(t)
-			R.neg()
-		}
-
-		np=u[1].nbits()
-		t.copy(modneg(u[1],q))
-		nn=t.nbits()
-		if nn<np {
-			u[1].copy(t)
-			Q.neg()
-		}
-
-		R=R.mul2(u[0],Q,u[1])
-			
-	} else {
-		R=P.mul(e)
-	}
-	return R
-}
-
-/* Multiply P by e in group G2 */
-func G2mul(P *ECP2,e *BIG) *ECP2 {
-	var R *ECP2
-	if (USE_GS_G2) {
-		var Q []*ECP2
-		f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-		q:=NewBIGints(CURVE_Order)
-		u:=gs(e)
-
-		t:=NewBIGint(0)
-		P.affine()
-		Q=append(Q,NewECP2());  Q[0].copy(P);
-		for i:=1;i<4;i++ {
-			Q=append(Q,NewECP2()); Q[i].copy(Q[i-1])
-			Q[i].frob(f)
-		}
-		for i:=0;i<4;i++ {
-			np:=u[i].nbits()
-			t.copy(modneg(u[i],q))
-			nn:=t.nbits()
-			if nn<np {
-				u[i].copy(t)
-				Q[i].neg()
-			}
-		}
-
-		R=mul4(Q,u)
-
-	} else {
-		R=P.mul(e)
-	}
-	return R
-}
-
-/* f=f^e */
-/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
-func GTpow(d *FP12,e *BIG) *FP12 {
-	var r *FP12
-	if USE_GS_GT {
-		var g []*FP12
-		f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-		q:=NewBIGints(CURVE_Order)
-		t:=NewBIGint(0)
-	
-		u:=gs(e)
-
-		g=append(g,NewFP12copy(d))
-		for i:=1;i<4;i++ {
-			g=append(g,NewFP12int(0))
-			g[i].copy(g[i-1])
-			g[i].frob(f)
-		}
-		for i:=0;i<4;i++ {
-			np:=u[i].nbits()
-			t.copy(modneg(u[i],q))
-			nn:=t.nbits()
-			if nn<np {
-				u[i].copy(t)
-				g[i].conj()
-			}
-		}
-		r=pow4(g,u)
-	} else {
-		r=d.pow(e)
-	}
-	return r
-}
-
-/* test group membership - no longer needed*/
-/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
-/*
-func GTmember(m *FP12) bool {
-	if m.isunity() {return false}
-	r:=NewFP12copy(m)
-	r.conj()
-	r.mul(m)
-	if !r.isunity() {return false}
-
-	f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb))
-
-	r.copy(m); r.frob(f); r.frob(f)
-	w:=NewFP12copy(r); w.frob(f); w.frob(f)
-	w.mul(m)
-	if !GT_STRONG {
-		if !w.equals(r) {return false}
-		x:=NewBIGints(CURVE_Bnx);
-		r.copy(m); w=r.pow(x); w=w.pow(x)
-		r.copy(w); r.sqr(); r.mul(w); r.sqr()
-		w.copy(m); w.frob(f)
-	}
-	return w.equals(r)
-}
-*/
-/*
-func main() {
-
-	Q:=NewECPbigs(NewBIGints(CURVE_Gx),NewBIGints(CURVE_Gy))
-	P:=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb)))
-
-	//r:=NewBIGints(CURVE_Order)
-	//xa:=NewBIGints(CURVE_Pxa)
-
-	fmt.Printf("P= "+P.toString())
-	fmt.Printf("\n");
-	fmt.Printf("Q= "+Q.toString());
-	fmt.Printf("\n");
-
-	//m:=NewBIGint(17)
-
-	e:=ate(P,Q)
-	e=fexp(e)
-	for i:=1;i<1000;i++ {
-		e=ate(P,Q)
-//	fmt.Printf("\ne= "+e.toString())
-//	fmt.Printf("\n")
-
-		e=fexp(e)
-	}
-	//	e=GTpow(e,m);
-
-	fmt.Printf("\ne= "+e.toString())
-	fmt.Printf("\n");
-	GLV:=glv(r)
-
-	fmt.Printf("GLV[0]= "+GLV[0].toString())
-	fmt.Printf("\n")
-
-	fmt.Printf("GLV[0]= "+GLV[1].toString())
-	fmt.Printf("\n")
-
-	G:=NewECP(); G.copy(Q)
-	R:=NewECP2(); R.copy(P)
-
-
-	e=ate(R,Q)
-	e=fexp(e)
-
-	e=GTpow(e,xa)
-	fmt.Printf("\ne= "+e.toString());
-	fmt.Printf("\n")
-
-	R=G2mul(R,xa)
-	e=ate(R,G)
-	e=fexp(e)
-
-	fmt.Printf("\ne= "+e.toString())
-	fmt.Printf("\n")
-
-	G=G1mul(G,xa)
-	e=ate(P,G)
-	e=fexp(e)
-	fmt.Printf("\ne= "+e.toString())
-	fmt.Printf("\n") 
-}
-*/

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/go/RAND.go
----------------------------------------------------------------------
diff --git a/version22/go/RAND.go b/version22/go/RAND.go
deleted file mode 100644
index 2b30ec4..0000000
--- a/version22/go/RAND.go
+++ /dev/null
@@ -1,153 +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.
-*/
-
-/*
- *   Cryptographic strong random number generator 
- *
- *   Unguessable seed -> SHA -> PRNG internal state -> SHA -> random numbers
- *   Slow - but secure
- *
- *   See ftp://ftp.rsasecurity.com/pub/pdfs/bull-1.pdf for a justification
- */
-
-/* Marsaglia & Zaman Random number generator constants */
-
-
-package main
-
-//import "fmt"
-
-const rand_NK int=21
-const rand_NJ int=6
-const rand_NV int=8
-
-type RAND struct {
-	ira [rand_NK]uint32  /* random number...   */
-	rndptr int
-	borrow uint32
-	pool_ptr int
-	pool [32]byte
-}
-
-/* Terminate and clean up */
-func (R *RAND) Clean() { /* kill internal state */
-	R.pool_ptr=0; R.rndptr=0;
-	for i:=0;i<32;i++ {R.pool[i]=0}
-	for i:=0;i<rand_NK;i++ {R.ira[i]=0}
-	R.borrow=0;
-}
-
-func NewRAND() *RAND {
-	R:=new(RAND)
-	R.Clean()
-	return R
-}
-
-func (R *RAND) sbrand() uint32 { /* Marsaglia & Zaman random number generator */
-	R.rndptr++
-	if R.rndptr<rand_NK {return R.ira[R.rndptr]}
-	R.rndptr=0
-	k:=rand_NK-rand_NJ
-	for i:=0;i<rand_NK;i++{ /* calculate next NK values */
-		if k==rand_NK {k=0}
-		t:=R.ira[k]
-		pdiff:=t-R.ira[i]-R.borrow
-		if pdiff<t {R.borrow=0}
-		if pdiff>t {R.borrow=1}
-		R.ira[i]=pdiff 
-		k++
-	}
-
-	return R.ira[0];
-}
-
-func (R *RAND) sirand(seed uint32) {
-	var m uint32=1;
-	R.borrow=0
-	R.rndptr=0
-	R.ira[0]^=seed;
-	for i:=1;i<rand_NK;i++ { /* fill initialisation vector */
-		in:=(rand_NV*i)%rand_NK;
-		R.ira[in]^=m;      /* note XOR */
-		t:=m
-		m=seed-m
-		seed=t
-	}
-	for i:=0;i<10000;i++ {R.sbrand()} /* "warm-up" & stir the generator */
-}
-
-func (R *RAND) fill_pool() {
-	sh:=NewHASH256()
-	for i:=0;i<128;i++ {sh.Process(byte(R.sbrand()&0xff))}
-	W:=sh.Hash()
-	for i:=0;i<32;i++ {R.pool[i]=W[i]}
-	R.pool_ptr=0;
-}
-
-func pack(b [4]byte) uint32 { /* pack 4 bytes into a 32-bit Word */
-	return (((uint32(b[3]))&0xff)<<24)|((uint32(b[2])&0xff)<<16)|((uint32(b[1])&0xff)<<8)|(uint32(b[0])&0xff)
-}
-
-/* Initialize RNG with some real entropy from some external source */
-func (R *RAND) Seed(rawlen int,raw []byte) { /* initialise from at least 128 byte string of raw random entropy */
-	var b [4]byte
-	sh:=NewHASH256()
-	R.pool_ptr=0;
-
-	for i:=0;i<rand_NK;i++ {R.ira[i]=0}
-	if rawlen>0 {
-		for i:=0;i<rawlen;i++ {
-			sh.Process(raw[i])
-		}
-		digest:=sh.Hash()
-
-/* initialise PRNG from distilled randomness */
-
-		for i:=0;i<8;i++  {
-			b[0]=digest[4*i]; b[1]=digest[4*i+1]; b[2]=digest[4*i+2]; b[3]=digest[4*i+3]
-			R.sirand(pack(b))
-		}
-	}
-	R.fill_pool()
-}
-
-/* get random byte */
-func (R *RAND) GetByte() byte { 
-	r:=R.pool[R.pool_ptr]
-	R.pool_ptr++
-	if R.pool_ptr>=32 {R.fill_pool()}
-	return byte(r&0xff)
-}
-
-/* test main program */
-/*
-func main() {
-	var raw [100]byte
-	rng:=NewRAND()
-
-	rng.Clean()
-	for i:=0;i<100;i++ {raw[i]=byte(i)}
-
-	rng.Seed(100,raw[:])
- 
-	for i:=0;i<1000;i++ {
-		fmt.Printf("%03d ",rng.GetByte())
-	}
-}
-*/