Skip to content

Instantly share code, notes, and snippets.

@hellais
Created March 16, 2015 15:24
Show Gist options
  • Save hellais/1d6a7ce672f0130b8f63 to your computer and use it in GitHub Desktop.
Save hellais/1d6a7ce672f0130b8f63 to your computer and use it in GitHub Desktop.
blind signatures
import os
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends.openssl.backend import Backend
from config import priv_key_path
def generate_private_key(private_key_path):
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with open(private_key_path, 'w+') as f:
for line in pem.splitlines():
f.write(line+"\n")
return private_key
def load_private_key(private_key_path):
with open(private_key_path, "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
return private_key
# private_key = generate_private_key(priv_key_path)
private_key = load_private_key(priv_key_path)
def blind(public_key, number):
e = public_key.public_numbers().e
n = public_key.public_numbers().n
backend = Backend()
bn_e = backend._int_to_bn(e)
bn_m = backend._int_to_bn(number)
bn_N = backend._int_to_bn(n)
with backend._tmp_bn_ctx() as bn_ctx:
bn_nonce_inv = backend._lib.BN_CTX_get(bn_ctx)
bn_re = backend._lib.BN_CTX_get(bn_ctx)
bn_mre = backend._lib.BN_CTX_get(bn_ctx)
bn_gcd = backend._lib.BN_CTX_get(bn_ctx)
nonce = int(os.urandom(256).encode('hex'), 16)
bn_nonce = backend._int_to_bn(nonce)
backend._lib.BN_gcd(bn_gcd, bn_nonce, bn_N, bn_ctx)
while backend._bn_to_int(bn_gcd) != 1:
nonce = int(os.urandom(256).encode('hex'), 16)
bn_nonce = backend._int_to_bn(nonce)
backend._lib.BN_gcd(bn_gcd, bn_nonce, bn_N, bn_ctx)
backend._lib.BN_mod_exp(bn_re, bn_nonce, bn_e, bn_N, bn_ctx)
backend._lib.BN_mod_mul(bn_mre, bn_re, bn_m, bn_N, bn_ctx)
mre = backend._bn_to_int(bn_mre)
backend._lib.BN_mod_inverse(bn_nonce_inv, bn_nonce, bn_N, bn_ctx)
nonce_inv = backend._bn_to_int(bn_nonce_inv)
return mre, nonce_inv
def blind_sign(private_key, message):
backend = Backend()
bn_mre = backend._int_to_bn(message)
bn_N = backend._int_to_bn(private_key.private_numbers().public_numbers.n)
bn_d = backend._int_to_bn(private_key.private_numbers().d)
with backend._tmp_bn_ctx() as bn_ctx:
bn_s = backend._lib.BN_CTX_get(bn_ctx)
backend._lib.BN_mod_exp(bn_s, bn_mre, bn_d, bn_N, bn_ctx)
s = backend._bn_to_int(bn_s)
return s
def unblind(public_key, blind_signed, nonce_inv):
backend = Backend()
bn_bs = backend._int_to_bn(blind_signed)
bn_N = backend._int_to_bn(private_key.public_key().public_numbers().n)
bn_nonce_inv = backend._int_to_bn(nonce_inv)
with backend._tmp_bn_ctx() as bn_ctx:
bn_s = backend._lib.BN_CTX_get(bn_ctx)
backend._lib.BN_mod_mul(bn_s, bn_bs, bn_nonce_inv, bn_N, bn_ctx)
s = backend._bn_to_int(bn_s)
return s
print "Blinding"
mre, nonce_inv = blind(private_key.public_key(), 420)
print "Blind signing"
blind_signed = blind_sign(private_key, mre)
print "Unblinding"
signed = unblind(private_key.public_key(), blind_signed, nonce_inv)
print signed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment