Я пытаюсь внедрить схему верификатора, назначенную JSO Java. Я следую за бумагой выше, чтобы осуществить это. Но я получаю очень странный результат, который иногда является успешным, а иногда неудачным.
Вот пример успеха и неудачи. стрелка шириной в две является результатом проверки LHS и RHS на бумаге.
Неудачный случай
JSI Designated Verifier Signature Instance : JSIDVS : [
p=11,
q=5,
g=5,
]
keyPairA = KeyPair : [
privateKey=2,
publicKey=3,
]
keyPairB = KeyPair : [
privateKey=2,
publicKey=3,
]
w = 3
r = 2
t = 3
Signature sign by A : JSIDVSSignature : [
s=4,
w=3,
r=2,
G=4,
M=8,
d=4,
]
9 <--> 9
6 <--> 5
false
Успешный случай
JSI Designated Verifier Signature Instance : JSIDVS : [
p=11,
q=5,
g=4,
]
keyPairA = KeyPair : [
privateKey=4,
publicKey=3,
]
keyPairB = KeyPair : [
privateKey=4,
publicKey=3,
]
w = 3
r = 4
t = 2
Signature sign by A : JSIDVSSignature : [
s=5,
w=3,
r=4,
G=5,
M=4,
d=2,
]
5 <--> 5
4 <--> 4
true
А ниже мой код в Java.
package hk.jeff.dvs;
import hk.jeff.CryptoUtils;
import hk.jeff.model.KeyPair;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.security.Signature;
public class JSIDVS {
protected static int RADIX = 10;
private int size;
BigInteger p;
BigInteger q;
BigInteger g;
public JSIDVS(BigInteger p, BigInteger q, BigInteger g){
this.p = p;
this.q = q;
this.g = g;
}
public JSIDVS(int size){
this.size = size;
SecureRandom random = new SecureRandom();
BigInteger[] primes = CryptoUtils.generateSafePrimes(this.size, 100, random);
this.p = primes[0];
this.q = primes[1];
this.g = CryptoUtils.selectGenerator(p, q, random);
}
@Override
public String toString() {
return "JSIDVS : [\n" +
" p=" + p.toString(RADIX) + ",\n" +
" q=" + q.toString(RADIX) + ",\n" +
" g=" + g.toString(RADIX) + ",\n" +
"]";
}
public KeyPair generateKeyPair(){
BigInteger x = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger y = this.g.modPow(x, this.p);
KeyPair kp = new KeyPair();
kp.setPublicKey(y);
kp.setPrivateKey(x);
return kp;
}
public JSIDVSSignature sign(BigInteger priKeyA, BigInteger pubKeyB, BigInteger m){
JSIDVSSignature signature = new JSIDVSSignature();
BigInteger w = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger r = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger t = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
// BigInteger w = BigInteger.valueOf(57);
// BigInteger r = BigInteger.valueOf(403);
// BigInteger t = BigInteger.valueOf(383);
System.out.println("w = " + w);
System.out.println("r = " + r);
System.out.println("t = " + t);
BigInteger s = m.modPow(priKeyA, p);
BigInteger c = (CryptoUtils.pow(g, w).multiply(CryptoUtils.pow(pubKeyB, r))).mod(p);
BigInteger G = g.modPow(t, p);
BigInteger M = m.modPow(t, p);
BigInteger h = this.hashq(c, G, M);
BigInteger d = t.add((priKeyA.multiply(h.add(w))).mod(q));
signature.s = s;
signature.w = w;
signature.r = r;
signature.G = G;
signature.M = M;
signature.d = d;
return signature;
}
public Boolean verify(JSIDVSSignature signature, BigInteger m, BigInteger pubKeyA, BigInteger pubKeyB){
BigInteger c = g.modPow(signature.w, p).multiply(pubKeyB.modPow(signature.r, p)).mod(p);
BigInteger h = this.hashq(c, signature.G, signature.M);
BigInteger lhs1 = (signature.G.multiply(CryptoUtils.pow(pubKeyA, h.add(signature.w)))).mod(p);
BigInteger rhs1 = g.modPow(signature.d, p);
BigInteger lhs2 = (signature.M.multiply(CryptoUtils.pow(signature.s, h.add(signature.w)))).mod(p);
BigInteger rhs2 = m.modPow(signature.d, p);
System.out.println(lhs1 + " <--> " + rhs1);
System.out.println(lhs2 + " <--> " + rhs2);
return lhs1.compareTo(rhs1) == 0 && lhs2.compareTo(rhs2) == 0;
}
public JSIDVSSignature simulate(BigInteger pubKeyA, BigInteger priKeyB, BigInteger m){
JSIDVSSignature signature = new JSIDVSSignature();
BigInteger d = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger a = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger b = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
BigInteger s = m.modPow(priKeyB, p);
BigInteger nb = b.multiply(BigInteger.valueOf(-1));
BigInteger c = g.modPow(a, p);
BigInteger G = g.modPow(d, p).multiply(pubKeyA.modPow(nb, p)).mod(p);
BigInteger M = m.modPow(d, p).multiply(s.modPow(nb, p)).mod(p);
BigInteger h = this.hashq(c, G, M);
BigInteger w = (b.subtract(h)).mod(q);
BigInteger r = ((a.subtract(w)).multiply(BigInteger.ONE.divide(priKeyB))).mod(q);
signature.s = s;
signature.w = w;
signature.r = r;
signature.G = G;
signature.M = M;
signature.d = d;
return signature;
}
private BigInteger hashq(BigInteger c, BigInteger G, BigInteger M){
BigInteger h = (c.add(G).add(M)).mod(q);
return h;
}
public static class JSIDVSSignature {
private BigInteger s;
private BigInteger w;
private BigInteger r;
private BigInteger G;
private BigInteger M;
private BigInteger d;
@Override
public String toString() {
return "JSIDVSSignature : [\n" +
" s=" + s.toString(RADIX) + ",\n" +
" w=" + w.toString(RADIX) + ",\n" +
" r=" + r.toString(RADIX) + ",\n" +
" G=" + G.toString(RADIX) + ",\n" +
" M=" + M.toString(RADIX) + ",\n" +
" d=" + d.toString(RADIX) + ",\n" +
"]";
}
public BigInteger getS() {
return s;
}
public void setS(BigInteger s) {
this.s = s;
}
public BigInteger getW() {
return w;
}
public void setW(BigInteger w) {
this.w = w;
}
public BigInteger getR() {
return r;
}
public void setR(BigInteger r) {
this.r = r;
}
public BigInteger getG() {
return G;
}
public void setG(BigInteger g) {
G = g;
}
public BigInteger getM() {
return M;
}
public void setM(BigInteger m) {
M = m;
}
public BigInteger getD() {
return d;
}
public void setD(BigInteger d) {
this.d = d;
}
}
}
и запустить его в main.
package hk.jeff;
import hk.jeff.dvs.JSIDVS;
import hk.jeff.model.KeyPair;
import java.math.BigInteger;
public class App {
public static void main( String[] args ) throws Exception{
JSIDVS dvs = new JSIDVS(4);
System.out.println("JSI Designated Verifier Signature Instance : " + dvs.toString());
KeyPair keyPairA = dvs.generateKeyPair();
KeyPair keyPairB = dvs.generateKeyPair();
System.out.println("keyPairA = " + keyPairA);
System.out.println("keyPairB = " + keyPairB);
BigInteger message = new BigInteger("2");
JSIDVS.JSIDVSSignature signature = dvs.sign(keyPairA.getPrivateKey(), keyPairB.getPublicKey(), message);
System.out.println("Signature sign by A : " + signature);
Boolean success = dvs.verify(signature, message, keyPairA.getPublicKey(), keyPairB.getPublicKey());
System.out.println(success);
}
}
<span class="math-container">```</span>