mirror of
https://github.com/luxfi/blst.git
synced 2026-10-30 17:01:37 +00:00
1203 lines
39 KiB
Python
Executable File
1203 lines
39 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright Supranational LLC
|
|
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
import shutil
|
|
import subprocess
|
|
|
|
emcc = shutil.which("emcc")
|
|
if emcc is None:
|
|
git_root = os.path.join(os.path.dirname(sys.argv[0]), "..", "..")
|
|
if os.name != 'posix' or not sys.stdin.isatty() or \
|
|
not os.path.isdir(os.path.join(git_root, ".git")) or \
|
|
not shutil.which("docker"):
|
|
print("FATAL: no 'emcc' on the program search path", file=sys.stderr)
|
|
sys.exit(2)
|
|
|
|
try:
|
|
answer = input("No 'emcc' found, do you want to try to build in docker [y/N]? ")
|
|
if not answer.startswith("y"):
|
|
sys.exit(2)
|
|
except KeyboardInterrupt:
|
|
sys.exit(2)
|
|
|
|
cmd = "git clone -q /blst /tmp/blst && " + \
|
|
"/tmp/blst/bindings/emscripten/build.py " + " ".join(sys.argv[1:])
|
|
subprocess.check_call([
|
|
"docker", "run",
|
|
"--volume={}:/blst".format(os.path.abspath(git_root)),
|
|
"--volume={}:/dst".format(os.getcwd()), "--workdir=/dst",
|
|
"--user={}:{}".format(os.getuid(), os.getgid()), "--userns=host",
|
|
"--network=none", "--rm",
|
|
"emscripten/emsdk", "sh", "-c", cmd
|
|
])
|
|
sys.exit(0)
|
|
|
|
common_cpp = """
|
|
#include <emscripten.h>
|
|
#include <blst.hpp>
|
|
using namespace blst;
|
|
#pragma GCC diagnostic ignored "-Wreturn-stack-address"
|
|
extern "C" {
|
|
|
|
EM_JS(void, blst_exception, (BLST_ERROR code), {
|
|
throw new Error(BLST_ERROR_str[code]);
|
|
});
|
|
"""
|
|
common_js = """
|
|
const BLST_ERROR_str = [
|
|
"BLST_ERROR: success",
|
|
"BLST_ERROR: bad point encoding",
|
|
"BLST_ERROR: point is not on curve",
|
|
"BLST_ERROR: point is not in group",
|
|
"BLST_ERROR: context type mismatch",
|
|
"BLST_ERROR: verify failed",
|
|
"BLST_ERROR: public key is infinite",
|
|
"BLST_ERROR: bad scalar",
|
|
];
|
|
"""
|
|
|
|
common_js += """
|
|
function unsupported(type, extra)
|
|
{ if (typeof extra === 'undefined')
|
|
return `${type ? type.constructor.name : 'none'}: unsupported type`;
|
|
else
|
|
return `${type ? type.constructor.name : 'none'}/${extra ? extra.constructor.name : 'none'}: unsupported types or combination thereof`;
|
|
}
|
|
|
|
function ensureAny(value)
|
|
{ if (value === null)
|
|
return [0, 0];
|
|
|
|
switch (value.constructor) {
|
|
case String:
|
|
return [ensureString(value), lengthBytesUTF8(value)];
|
|
case ArrayBuffer:
|
|
return [ensureInt8(new Uint8Array(value)), value.byteLength];
|
|
case BigInt:
|
|
if (value < 0)
|
|
throw new Error("expecting unsigned BigInt value");
|
|
var temp = [];
|
|
while (value != 0) {
|
|
temp.push(Number(value & 255n));
|
|
value >>= 8n;
|
|
}
|
|
return [ensureInt8(temp), temp.length];
|
|
case Uint8Array: case Buffer:
|
|
return [ensureInt8(value), value.length];
|
|
default:
|
|
throw new Error(unsupported(value));
|
|
}
|
|
}
|
|
"""
|
|
|
|
# ###### Constants
|
|
common_cpp += """
|
|
const P1_Affine* EMSCRIPTEN_KEEPALIVE const_G1()
|
|
{ return reinterpret_cast<const P1_Affine*>(&BLS12_381_G1); }
|
|
const P2_Affine* EMSCRIPTEN_KEEPALIVE const_G2()
|
|
{ return reinterpret_cast<const P2_Affine*>(&BLS12_381_G2); }
|
|
const P1_Affine* EMSCRIPTEN_KEEPALIVE const_NEG_G1()
|
|
{ return reinterpret_cast<const P1_Affine*>(&BLS12_381_NEG_G1); }
|
|
const P2_Affine* EMSCRIPTEN_KEEPALIVE const_NEG_G2()
|
|
{ return reinterpret_cast<const P2_Affine*>(&BLS12_381_NEG_G2); }
|
|
"""
|
|
common_js += """
|
|
(function() {
|
|
function setupConsts() {
|
|
var i = 0;
|
|
Module['BLST_SUCCESS'] = i++;
|
|
Module['BLST_BAD_ENCODING'] = i++;
|
|
Module['BLST_POINT_NOT_ON_CURVE'] = i++;
|
|
Module['BLST_POINT_NOT_IN_GROUP'] = i++;
|
|
Module['BLST_AGGR_TYPE_MISMATCH'] = i++;
|
|
Module['BLST_VERIFY_FAIL'] = i++;
|
|
Module['BLST_PK_IS_INFINITY'] = i++;
|
|
Module['BLST_BAD_SCALAR'] = i++;
|
|
Module['BLS12_381_G1'] = wrapPointer(_const_G1(), P1_Affine);
|
|
Module['BLS12_381_G2'] = wrapPointer(_const_G2(), P2_Affine);
|
|
Module['BLS12_381_NEG_G1'] = wrapPointer(_const_NEG_G1(), P1_Affine);
|
|
Module['BLS12_381_NEG_G2'] = wrapPointer(_const_NEG_G2(), P2_Affine);
|
|
}
|
|
if (runtimeInitialized) setupConsts();
|
|
else addOnInit(setupConsts);
|
|
})();
|
|
"""
|
|
|
|
# ###### P1_Affine
|
|
p1_cpp = """
|
|
P1_Affine* EMSCRIPTEN_KEEPALIVE P1_Affine_0()
|
|
{ return new P1_Affine(); }
|
|
P1_Affine* EMSCRIPTEN_KEEPALIVE P1_Affine_1(const P1* input)
|
|
{ return new P1_Affine(*input); }
|
|
P1_Affine* EMSCRIPTEN_KEEPALIVE P1_Affine_2(const byte* input, size_t len)
|
|
{ try { return new P1_Affine(input, len); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
return nullptr;
|
|
}
|
|
void EMSCRIPTEN_KEEPALIVE P1_Affine__destroy__0(P1_Affine* self)
|
|
{ delete self; }
|
|
"""
|
|
p1_js = """
|
|
/** @this{Object} */
|
|
function P1_Affine(input)
|
|
{ ensureCache.prepare();
|
|
if (typeof input === 'undefined' || input === null)
|
|
this.ptr = _P1_Affine_0();
|
|
else if (input instanceof Uint8Array)
|
|
this.ptr = _P1_Affine_2(ensureInt8(input), input.length);
|
|
else if (input instanceof P1)
|
|
this.ptr = _P1_Affine_1(input.ptr);
|
|
else
|
|
throw new Error(unsupported(input));
|
|
getCache(P1_Affine)[this.ptr] = this;
|
|
}
|
|
P1_Affine.prototype = Object.create(WrapperObject.prototype);
|
|
P1_Affine.prototype.constructor = P1_Affine;
|
|
P1_Affine.prototype.__class__ = P1_Affine;
|
|
P1_Affine.__cache__ = {};
|
|
Module['P1_Affine'] = P1_Affine;
|
|
P1_Affine.prototype['__destroy__'] = P1_Affine.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _P1_Affine__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
p1_cpp += """
|
|
P1_Affine* EMSCRIPTEN_KEEPALIVE P1_Affine_dup_0(const P1_Affine* self)
|
|
{ return new P1_Affine(self->dup()); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['dup'] = P1_Affine.prototype.dup = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_P1_Affine_dup_0(this.ptr), P1_Affine); };;
|
|
"""
|
|
p1_cpp += """
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_Affine_to_jacobian_0(const P1_Affine* self)
|
|
{ return new P1(self->to_jacobian()); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['to_jacobian'] = P1_Affine.prototype.to_jacobian = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_P1_Affine_to_jacobian_0(this.ptr), P1); };;
|
|
"""
|
|
p1_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE P1_Affine_serialize_0(const P1_Affine* self)
|
|
{ byte out[96*1];
|
|
self->serialize(out);
|
|
return out;
|
|
}
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['serialize'] = P1_Affine.prototype.serialize = /** @this{Object} */
|
|
function()
|
|
{ var out = _P1_Affine_serialize_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 96*1));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE P1_Affine_compress_0(const P1_Affine* self)
|
|
{ byte out[48*1];
|
|
self->compress(out);
|
|
return out;
|
|
}
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['compress'] = P1_Affine.prototype.compress = /** @this{Object} */
|
|
function()
|
|
{ var out = _P1_Affine_compress_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 48*1));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_Affine_on_curve_0(const P1_Affine* self)
|
|
{ return self->on_curve(); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['on_curve'] = P1_Affine.prototype.on_curve = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_Affine_on_curve_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_Affine_in_group_0(const P1_Affine* self)
|
|
{ return self->in_group(); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['in_group'] = P1_Affine.prototype.in_group = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_Affine_in_group_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_Affine_is_inf_0(const P1_Affine* self)
|
|
{ return self->is_inf(); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['is_inf'] = P1_Affine.prototype.is_inf = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_Affine_is_inf_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_Affine_is_equal_1(const P1_Affine* self, const P1_Affine* p)
|
|
{ return self->is_equal(*p); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['is_equal'] = P1_Affine.prototype.is_equal = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof P1_Affine)
|
|
return !!(_P1_Affine_is_equal_1(this.ptr, p.ptr));
|
|
throw new Error(unsupported(p));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
int EMSCRIPTEN_KEEPALIVE P1_Affine_core_verify_7(const P1_Affine* self,
|
|
const P2_Affine* pk, bool hash_or_encode,
|
|
const byte* msg, size_t msg_len,
|
|
const char* DST,
|
|
const byte* aug, size_t aug_len)
|
|
{ return self->core_verify(*pk, hash_or_encode, msg, msg_len, DST ? DST : "", aug, aug_len); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine.prototype['core_verify'] = P1_Affine.prototype.core_verify = /** @this{Object} */
|
|
function(pk, hash_or_encode, msg, DST, aug)
|
|
{ if (!(pk instanceof P2_Affine))
|
|
throw new Error(unsupported(pk));
|
|
ensureCache.prepare();
|
|
const [_msg, msg_len] = ensureAny(msg);
|
|
DST = ensureString(DST);
|
|
const [_aug, aug_len] = ensureAny(aug);
|
|
return _P1_Affine_core_verify_7(this.ptr, pk.ptr, !!hash_or_encode, _msg, msg_len, DST, _aug, aug_len);
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
P1_Affine* EMSCRIPTEN_KEEPALIVE P1_Affine_generator_0()
|
|
{ return new P1_Affine(P1_Affine::generator()); }
|
|
"""
|
|
p1_js += """
|
|
P1_Affine['generator'] = P1_Affine.generator =
|
|
function()
|
|
{ return wrapPointer(_P1_Affine_generator_0(), P1_Affine); };;
|
|
"""
|
|
|
|
# ###### P1
|
|
p1_cpp += """
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_0()
|
|
{ return new P1(); }
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_affine_1(const P1_Affine* p)
|
|
{ return new P1(*p); }
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_secretkey_1(const SecretKey* sk)
|
|
{ return new P1(*sk); }
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_2(const byte* input, size_t len)
|
|
{ try { return new P1(input, len); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
return nullptr;
|
|
}
|
|
void EMSCRIPTEN_KEEPALIVE P1__destroy__0(P1* self)
|
|
{ delete self; }
|
|
"""
|
|
p1_js += """
|
|
/** @this{Object} */
|
|
function P1(input)
|
|
{ ensureCache.prepare();
|
|
if (typeof input === 'undefined' || input === null)
|
|
this.ptr = _P1_0();
|
|
else if (input instanceof Uint8Array)
|
|
this.ptr = _P1_2(ensureInt8(input), input.length);
|
|
else if (input instanceof P1_Affine)
|
|
this.ptr = _P1_affine_1(input.ptr);
|
|
else if (input instanceof SecretKey)
|
|
this.ptr = _P1_secretkey_1(input.ptr);
|
|
else
|
|
throw new Error(unsupported(input));
|
|
getCache(P1)[this.ptr] = this;
|
|
}
|
|
P1.prototype = Object.create(WrapperObject.prototype);
|
|
P1.prototype.constructor = P1;
|
|
P1.prototype.__class__ = P1;
|
|
P1.__cache__ = {};
|
|
Module['P1'] = P1;
|
|
P1.prototype['__destroy__'] = P1.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _P1__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
p1_cpp += """
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_dup_0(const P1* self)
|
|
{ return new P1(self->dup()); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['dup'] = P1.prototype.dup = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_P1_dup_0(this.ptr), P1); };;
|
|
"""
|
|
p1_cpp += """
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_to_affine_0(const P1* self)
|
|
{ return new P1(self->to_affine()); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['to_affine'] = P1.prototype.to_affine = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_P1_to_affine_0(this.ptr), P1_Affine); };;
|
|
"""
|
|
p1_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE P1_serialize_0(const P1* self)
|
|
{ byte out[96*1];
|
|
self->serialize(out);
|
|
return out;
|
|
}
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['serialize'] = P1.prototype.serialize = /** @this{Object} */
|
|
function()
|
|
{ var out = _P1_serialize_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 96*1));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE P1_compress_0(const P1* self)
|
|
{ byte out[48*1];
|
|
self->compress(out);
|
|
return out;
|
|
}
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['compress'] = P1.prototype.compress = /** @this{Object} */
|
|
function()
|
|
{ var out = _P1_compress_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 48*1));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_on_curve_0(const P1* self)
|
|
{ return self->on_curve(); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['on_curve'] = P1.prototype.on_curve = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_on_curve_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_in_group_0(const P1* self)
|
|
{ return self->in_group(); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['in_group'] = P1.prototype.in_group = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_in_group_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_is_inf_0(const P1* self)
|
|
{ return self->is_inf(); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['is_inf'] = P1.prototype.is_inf = /** @this{Object} */
|
|
function()
|
|
{ return !!(_P1_is_inf_0(this.ptr)); };;
|
|
"""
|
|
p1_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE P1_is_equal_1(const P1* self, const P1* p)
|
|
{ return self->is_equal(*p); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['is_equal'] = P1.prototype.is_equal = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof P1)
|
|
return !!(_P1_is_equal_1(this.ptr, p.ptr));
|
|
throw new Error(unsupported(p));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_aggregate_1(P1* self, const P1_Affine* p)
|
|
{ try { self->aggregate(*p); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
}
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['aggregate'] = P1.prototype.aggregate = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof P1_Affine)
|
|
_P1_aggregate_1(this.ptr, p.ptr);
|
|
else
|
|
throw new Error(unsupported(p));
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_sign_with_1(P1* self, const SecretKey* sk)
|
|
{ (void)self->sign_with(*sk); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['sign_with'] = P1.prototype.sign_with = /** @this{Object} */
|
|
function(sk)
|
|
{ if (sk instanceof SecretKey)
|
|
_P1_sign_with_1(this.ptr, sk.ptr);
|
|
else
|
|
throw new Error(unsupported(sk));
|
|
return this;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_hash_to_5(P1* self, const byte* msg, size_t msg_len,
|
|
const char* DST,
|
|
const byte* aug, size_t aug_len)
|
|
{ (void)self->hash_to(msg, msg_len, DST ? DST : "", aug, aug_len); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['hash_to'] = P1.prototype.hash_to = /** @this{Object} */
|
|
function(msg, DST, aug)
|
|
{ ensureCache.prepare();
|
|
const [_msg, msg_len] = ensureAny(msg);
|
|
DST = ensureString(DST);
|
|
const [_aug, aug_len] = ensureAny(aug);
|
|
_P1_hash_to_5(this.ptr, _msg, msg_len, DST, _aug, aug_len);
|
|
return this;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_encode_to_5(P1* self, const byte* msg, size_t msg_len,
|
|
const char* DST,
|
|
const byte* aug, size_t aug_len)
|
|
{ (void)self->encode_to(msg, msg_len, DST ? DST : "", aug, aug_len); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['encode_to'] = P1.prototype.encode_to = /** @this{Object} */
|
|
function(msg, DST, aug)
|
|
{ ensureCache.prepare();
|
|
const [_msg, msg_len] = ensureAny(msg);
|
|
DST = ensureString(DST);
|
|
const [_aug, aug_len] = ensureAny(aug);
|
|
_P1_encode_to_5(this.ptr, _msg, msg_len, DST, _aug, aug_len);
|
|
return this;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_mult_1(P1* self, const Scalar* scalar)
|
|
{ (void)self->mult(*scalar); }
|
|
void EMSCRIPTEN_KEEPALIVE P1_mult_2(P1* self, const byte* scalar, size_t nbits)
|
|
{ (void)self->mult(scalar, nbits); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['mult'] = P1.prototype.mult = /** @this{Object} */
|
|
function(scalar)
|
|
{ if (scalar instanceof Scalar) {
|
|
_P1_mult_1(this.ptr, scalar.ptr);
|
|
} else if (typeof scalar !== 'string') {
|
|
ensureCache.prepare();
|
|
const [_scalar, len] = ensureAny(scalar);
|
|
_P1_mult_2(this.ptr, _scalar, len*8);
|
|
} else {
|
|
throw new Error(unsupported(scalar));
|
|
}
|
|
return this;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_cneg_1(P1* self, bool flag)
|
|
{ (void)self->cneg(flag); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['cneg'] = P1.prototype.cneg = /** @this{Object} */
|
|
function(flag)
|
|
{ _P1_cneg_1(this.ptr, !!flag); return this; };;
|
|
P1.prototype['neg'] = P1.prototype.neg = /** @this{Object} */
|
|
function()
|
|
{ _P1_cneg_1(this.ptr, true); return this; };;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_add_1(P1* self, const P1* a)
|
|
{ (void)self->add(*a); }
|
|
void EMSCRIPTEN_KEEPALIVE P1_add_affine_1(P1* self, const P1_Affine* a)
|
|
{ (void)self->add(*a); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['add'] = P1.prototype.add = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof P1)
|
|
_P1_add_1(this.ptr, p.ptr);
|
|
else if (p instanceof P1_Affine)
|
|
_P1_add_affine_1(this.ptr, p.ptr);
|
|
else
|
|
throw new Error(unsupported(p));
|
|
return this;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE P1_dbl_0(P1* self)
|
|
{ (void)self->dbl(); }
|
|
"""
|
|
p1_js += """
|
|
P1.prototype['dbl'] = P1.prototype.dbl = /** @this{Object} */
|
|
function()
|
|
{ _P1_dbl_0(this.ptr); return this; };;
|
|
"""
|
|
p1_cpp += """
|
|
P1* EMSCRIPTEN_KEEPALIVE P1_generator_0()
|
|
{ return new P1(P1::generator()); }
|
|
"""
|
|
p1_js += """
|
|
Module['G1'] = P1['generator'] = P1.generator =
|
|
function()
|
|
{ return wrapPointer(_P1_generator_0(), P1); };;
|
|
"""
|
|
|
|
# ###### SecretKey
|
|
common_cpp += """
|
|
SecretKey* EMSCRIPTEN_KEEPALIVE SecretKey_0()
|
|
{ return new SecretKey(); }
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey__destroy__0(SecretKey* self)
|
|
{ explicit_bzero((void*)self, sizeof(*self)); delete self; }
|
|
"""
|
|
common_js += """
|
|
/** @this{Object} */
|
|
function SecretKey()
|
|
{ this.ptr = _SecretKey_0();
|
|
getCache(SecretKey)[this.ptr] = this;
|
|
}
|
|
SecretKey.prototype = Object.create(WrapperObject.prototype);
|
|
SecretKey.prototype.constructor = SecretKey;
|
|
SecretKey.prototype.__class__ = SecretKey;
|
|
SecretKey.__cache__ = {};
|
|
Module['SecretKey'] = SecretKey;
|
|
SecretKey.prototype['__destroy__'] = SecretKey.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _SecretKey__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey_keygen_3(SecretKey* self, const byte* IKM, size_t IKM_len, const char* info)
|
|
{ self->keygen(IKM, IKM_len, info ? info : ""); }
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['keygen'] = SecretKey.prototype.keygen = /** @this{Object} */
|
|
function(IKM, info)
|
|
{ ensureCache.prepare();
|
|
const [_IKM, IKM_len] = ensureAny(IKM);
|
|
if (IKM_len < 32)
|
|
throw new Error("BLST_ERROR: bad scalar");
|
|
info = ensureString(info);
|
|
_SecretKey_keygen_3(this.ptr, _IKM, IKM_len, info);
|
|
HEAP8.fill(0, _IKM, _IKM + IKM_len);
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey_derive_master_eip2333_2(SecretKey* self, const byte* IKM, size_t IKM_len)
|
|
{ self->derive_master_eip2333(IKM, IKM_len); }
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['derive_master_eip2333'] = SecretKey.prototype.derive_master_eip2333 = /** @this{Object} */
|
|
function(IKM)
|
|
{ ensureCache.prepare();
|
|
const [_IKM, IKM_len] = ensureAny(IKM);
|
|
if (IKM_len < 32)
|
|
throw new Error("BLST_ERROR: bad scalar");
|
|
_SecretKey_derive_master_eip2333_2(this.ptr, _IKM, IKM_len);
|
|
HEAP8.fill(0, _IKM, _IKM + IKM_len);
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey_derive_child_eip2333_2(SecretKey* self, const SecretKey* sk, unsigned int child_index)
|
|
{ self->derive_child_eip2333(*sk, child_index); }
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['derive_child_eip2333'] = SecretKey.prototype.derive_child_eip2333 = /** @this{Object} */
|
|
function(sk, child_index)
|
|
{ if (!(sk instanceof SecretKey))
|
|
throw new Error(unsupported(sk));
|
|
_SecretKey_derive_child_eip2333_2(this.ptr, sk.ptr, child_index);
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey_from_bendian_1(SecretKey* self, const byte* sk)
|
|
{ self->from_bendian(sk); }
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['from_bendian'] = SecretKey.prototype.from_bendian = /** @this{Object} */
|
|
function(sk)
|
|
{ if (!(sk instanceof Uint8Array) || sk.length != 32)
|
|
throw new Error(unsupported(sk));
|
|
ensureCache.prepare();
|
|
sk = ensureInt8(sk);
|
|
_SecretKey_from_bendian_1(this.ptr, sk);
|
|
HEAP8.fill(0, sk, sk + 32);
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE SecretKey_from_lendian_1(SecretKey* self, const byte* sk)
|
|
{ self->from_lendian(sk); }
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['from_lendian'] = SecretKey.prototype.from_lendian = /** @this{Object} */
|
|
function(sk)
|
|
{ if (!(sk instanceof Uint8Array) || sk.length != 32)
|
|
throw new Error(unsupported(sk));
|
|
ensureCache.prepare();
|
|
sk = ensureInt8(sk);
|
|
_SecretKey_from_lendian_1(this.ptr, sk);
|
|
HEAP8.fill(0, sk, sk + 32);
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE SecretKey_to_bendian_0(const SecretKey* self)
|
|
{ byte out[32];
|
|
self->to_bendian(out);
|
|
return out;
|
|
}
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['to_bendian'] = SecretKey.prototype.to_bendian = /** @this{Object} */
|
|
function()
|
|
{ var out = _SecretKey_to_bendian_0(this.ptr);
|
|
var ret = new Uint8Array(HEAPU8.subarray(out, out + 32));
|
|
HEAP8.fill(0, out, out + 32);
|
|
return ret;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE SecretKey_to_lendian_0(const SecretKey* self)
|
|
{ byte out[32];
|
|
self->to_lendian(out);
|
|
return out;
|
|
}
|
|
"""
|
|
common_js += """
|
|
SecretKey.prototype['to_lendian'] = SecretKey.prototype.to_lendian = /** @this{Object} */
|
|
function()
|
|
{ var out = _SecretKey_to_lendian_0(this.ptr);
|
|
var ret = new Uint8Array(HEAPU8.subarray(out, out + 32));
|
|
HEAP8.fill(0, out, out + 32);
|
|
return ret;
|
|
};;
|
|
"""
|
|
|
|
# ###### Scalar
|
|
common_cpp += """
|
|
Scalar* EMSCRIPTEN_KEEPALIVE Scalar_0()
|
|
{ return new Scalar(); }
|
|
Scalar* EMSCRIPTEN_KEEPALIVE Scalar_2(const byte* scalar, size_t nbits)
|
|
{ return new Scalar(scalar, nbits); }
|
|
Scalar* EMSCRIPTEN_KEEPALIVE Scalar_3(const byte* msg, size_t msg_len, const char* DST)
|
|
{ return new Scalar(msg, msg_len, DST ? DST : ""); }
|
|
void EMSCRIPTEN_KEEPALIVE Scalar__destroy__0(Scalar* self)
|
|
{ delete self; }
|
|
"""
|
|
common_js += """
|
|
/** @this{Object} */
|
|
function Scalar(scalar, DST)
|
|
{ if (typeof scalar === 'undefined' || scalar === null) {
|
|
this.ptr = _Scalar_0();
|
|
} else {
|
|
ensureCache.prepare();
|
|
const [ _scalar, len] = ensureAny(scalar);
|
|
if (typeof DST === 'string' || DST === null) {
|
|
DST = ensureString(DST);
|
|
this.ptr = _Scalar_3(_scalar, len, DST);
|
|
} else {
|
|
this.ptr = _Scalar_2(_scalar, len*8);
|
|
}
|
|
}
|
|
getCache(Scalar)[this.ptr] = this;
|
|
}
|
|
Scalar.prototype = Object.create(WrapperObject.prototype);
|
|
Scalar.prototype.constructor = Scalar;
|
|
Scalar.prototype.__class__ = Scalar;
|
|
Scalar.__cache__ = {};
|
|
Module['Scalar'] = Scalar;
|
|
Scalar.prototype['__destroy__'] = Scalar.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _Scalar__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_hash_to_3(Scalar* self, const byte* msg, size_t msg_len, const char* DST)
|
|
{ (void)self->hash_to(msg, msg_len, DST ? DST : ""); }
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['hash_to'] = Scalar.prototype.hash_to = /** @this{Object} */
|
|
function(msg, DST)
|
|
{ ensureCache.prepare();
|
|
const [ _msg, msg_len] = ensureAny(msg);
|
|
DST = ensureString(DST);
|
|
_Scalar_hash_to_3(this.ptr, _msg, msg_len, DST);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
Scalar* EMSCRIPTEN_KEEPALIVE Scalar_dup_0(const Scalar* self)
|
|
{ return new Scalar(self->dup()); }
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['dup'] = Scalar.prototype.dup = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_Scalar_dup_0(this.ptr), Scalar); };;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_from_bendian_2(Scalar* self, const byte* msg, size_t msg_len)
|
|
{ (void)self->from_bendian(msg, msg_len); }
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['from_bendian'] = Scalar.prototype.from_bendian = /** @this{Object} */
|
|
function(msg)
|
|
{ ensureCache.prepare();
|
|
const [ _msg, msg_len] = ensureAny(msg);
|
|
_Scalar_from_bendian_2(this.ptr, _msg, msg_len);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_from_lendian_2(Scalar* self, const byte* msg, size_t msg_len)
|
|
{ (void)self->from_lendian(msg, msg_len); }
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['from_lendian'] = Scalar.prototype.from_lendian = /** @this{Object} */
|
|
function(msg)
|
|
{ ensureCache.prepare();
|
|
const [ _msg, msg_len] = ensureAny(msg);
|
|
_Scalar_from_lendian_2(this.ptr, _msg, msg_len);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE Scalar_to_bendian_0(const Scalar* self)
|
|
{ byte out[32];
|
|
self->to_bendian(out);
|
|
return out;
|
|
}
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['to_bendian'] = Scalar.prototype.to_bendian = /** @this{Object} */
|
|
function()
|
|
{ var out = _Scalar_to_bendian_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 32));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE Scalar_to_lendian_0(const Scalar* self)
|
|
{ byte out[32];
|
|
self->to_lendian(out);
|
|
return out;
|
|
}
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['to_lendian'] = Scalar.prototype.to_lendian = /** @this{Object} */
|
|
function()
|
|
{ var out = _Scalar_to_lendian_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 32));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_add_1(Scalar* self, const Scalar* a)
|
|
{ try { (void)self->add(*a); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
}
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['add'] = Scalar.prototype.add = /** @this{Object} */
|
|
function(a)
|
|
{ if (!(a instanceof Scalar || a instanceof SecretKey))
|
|
throw new Error(unsupported(a));
|
|
_Scalar_add_1(this.ptr, a.ptr);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_sub_1(Scalar* self, const Scalar* a)
|
|
{ try { (void)self->sub(*a); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
}
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['sub'] = Scalar.prototype.sub = /** @this{Object} */
|
|
function(a)
|
|
{ if (!(a instanceof Scalar))
|
|
throw new Error(unsupported(a));
|
|
_Scalar_sub_1(this.ptr, a.ptr);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_mul_1(Scalar* self, const Scalar* a)
|
|
{ try { (void)self->mul(*a); }
|
|
catch (const BLST_ERROR& e) { blst_exception(e); }
|
|
}
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['mul'] = Scalar.prototype.mul = /** @this{Object} */
|
|
function(a)
|
|
{ if (!(a instanceof Scalar))
|
|
throw new Error(unsupported(a));
|
|
_Scalar_mul_1(this.ptr, a.ptr);
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Scalar_inverse_0(Scalar* self)
|
|
{ (void)self->inverse(); }
|
|
"""
|
|
common_js += """
|
|
Scalar.prototype['inverse'] = Scalar.prototype.inverse = /** @this{Object} */
|
|
function()
|
|
{ _Scalar_inverse_0(this.ptr); return this; };;
|
|
"""
|
|
|
|
# ###### PT
|
|
common_cpp += """
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_p_affine_1(const P1_Affine* p)
|
|
{ return new PT(*p); }
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_q_affine_1(const P2_Affine* q)
|
|
{ return new PT(*q); }
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_pq_affine_2(const P1_Affine* p, const P2_Affine* q)
|
|
{ return new PT(*p, *q); }
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_pq_2(const P1* p, const P2* q)
|
|
{ return new PT(*p, *q); }
|
|
void EMSCRIPTEN_KEEPALIVE PT__destroy__0(PT* self)
|
|
{ delete self; }
|
|
"""
|
|
common_js += """
|
|
/** @this{Object} */
|
|
function PT(p, q)
|
|
{ if (typeof q === 'undefined' || q === null) {
|
|
if (p instanceof P1_Affine)
|
|
this.ptr = _PT_p_affine_1(p.ptr);
|
|
else if (p instanceof P2_Affine)
|
|
this.ptr = _PT_q_affine_1(p.ptr);
|
|
else
|
|
throw new Error(unsupported(p));
|
|
} else if (p instanceof P1_Affine && q instanceof P2_Affine) {
|
|
this.ptr = _PT_pq_affine_2(p.ptr, q.ptr);
|
|
} else if (p instanceof P2_Affine && q instanceof P1_Affine) {
|
|
this.ptr = _PT_pq_affine_2(q.ptr, p.ptr);
|
|
} else if (p instanceof P1 && q instanceof P2) {
|
|
this.ptr = _PT_pq_2(p.ptr, q.ptr);
|
|
} else if (p instanceof P2 && q instanceof P1) {
|
|
this.ptr = _PT_pq_2(q.ptr, p.ptr);
|
|
} else {
|
|
throw new Error(unsupported(p, q));
|
|
}
|
|
getCache(PT)[this.ptr] = this;
|
|
}
|
|
PT.prototype = Object.create(WrapperObject.prototype);
|
|
PT.prototype.constructor = PT;
|
|
PT.prototype.__class__ = PT;
|
|
PT.__cache__ = {};
|
|
Module['PT'] = PT;
|
|
PT.prototype['__destroy__'] = PT.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _PT__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
common_cpp += """
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_dup_0(const PT* self)
|
|
{ return new PT(self->dup()); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['dup'] = PT.prototype.dup = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_PT_dup_0(this.ptr), PT); };;
|
|
"""
|
|
common_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE PT_is_one_0(const PT* self)
|
|
{ return self->is_one(); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['is_one'] = PT.prototype.is_one = /** @this{Object} */
|
|
function()
|
|
{ return !!(_PT_is_one_0(this.ptr)); };;
|
|
"""
|
|
common_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE PT_is_equal_1(const PT* self, const PT* p)
|
|
{ return self->is_equal(*p); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['is_equal'] = PT.prototype.is_equal = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof PT)
|
|
return !!(_PT_is_equal_1(this.ptr, p.ptr));
|
|
throw new Error(unsupported(p));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE PT_sqr_0(PT* self)
|
|
{ (void)self->sqr(); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['sqr'] = PT.prototype.sqr = /** @this{Object} */
|
|
function()
|
|
{ _PT_sqr_0(this.ptr); return this; };;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE PT_mul_1(PT* self, const PT* p)
|
|
{ (void)self->mul(*p); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['mul'] = PT.prototype.mul = /** @this{Object} */
|
|
function(p)
|
|
{ if (p instanceof PT)
|
|
_PT_mul_1(this.ptr, p.ptr);
|
|
else
|
|
throw new Error(unsupported(p));
|
|
return this;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE PT_final_exp_0(PT* self)
|
|
{ (void)self->final_exp(); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['final_exp'] = PT.prototype.final_exp = /** @this{Object} */
|
|
function()
|
|
{ _PT_final_exp_0(this.ptr); return this; };;
|
|
"""
|
|
common_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE PT_in_group_0(const PT* self)
|
|
{ return self->in_group(); }
|
|
"""
|
|
common_js += """
|
|
PT.prototype['in_group'] = PT.prototype.in_group = /** @this{Object} */
|
|
function()
|
|
{ return !!(_PT_in_group_0(this.ptr)); };;
|
|
"""
|
|
common_cpp += """
|
|
byte* EMSCRIPTEN_KEEPALIVE PT_to_bendian_0(const PT* self)
|
|
{ byte out[48*12];
|
|
self->to_bendian(out);
|
|
return out;
|
|
}
|
|
"""
|
|
common_js += """
|
|
PT.prototype['to_bendian'] = PT.prototype.to_bendian = /** @this{Object} */
|
|
function()
|
|
{ var out = _PT_to_bendian_0(this.ptr);
|
|
return new Uint8Array(HEAPU8.subarray(out, out + 48*12));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE PT_finalverify_2(const PT* gt1, const PT* gt2)
|
|
{ return PT::finalverify(*gt1, *gt2); }
|
|
"""
|
|
common_js += """
|
|
PT['finalverify'] = PT.finalverify =
|
|
function(gt1, gt2)
|
|
{ if (gt1 instanceof PT && gt2 instanceof PT)
|
|
return !!(_PT_finalverify_2(gt1.ptr, gt2.ptr));
|
|
throw new Error(unsupported(gt1, gt2));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
PT* EMSCRIPTEN_KEEPALIVE PT_one_0()
|
|
{ return new PT(PT::one()); }
|
|
"""
|
|
common_js += """
|
|
PT['one'] = PT.one =
|
|
function()
|
|
{ return wrapPointer(_PT_one_0(), PT); };;
|
|
"""
|
|
|
|
# ###### Pairing
|
|
common_cpp += """
|
|
Pairing* EMSCRIPTEN_KEEPALIVE Pairing_2(bool hash_or_encode, const char* DST)
|
|
{ return new Pairing(hash_or_encode, std::string{DST ? DST : ""}); }
|
|
void EMSCRIPTEN_KEEPALIVE Pairing__destroy__0(Pairing* self)
|
|
{ delete self; }
|
|
"""
|
|
common_js += """
|
|
/** @this{Object} */
|
|
function Pairing(hash_or_encode, DST)
|
|
{ ensureCache.prepare();
|
|
DST = ensureString(DST);
|
|
this.ptr = _Pairing_2(!!hash_or_encode, DST);
|
|
getCache(SecretKey)[this.ptr] = this;
|
|
}
|
|
Pairing.prototype = Object.create(WrapperObject.prototype);
|
|
Pairing.prototype.constructor = Pairing;
|
|
Pairing.prototype.__class__ = Pairing;
|
|
Pairing.__cache__ = {};
|
|
Module['Pairing'] = Pairing;
|
|
Pairing.prototype['__destroy__'] = Pairing.prototype.__destroy__ = /** @this{Object} */
|
|
function()
|
|
{ _Pairing__destroy__0(this.ptr); this.ptr = 0; };;
|
|
"""
|
|
p1_cpp += """
|
|
int EMSCRIPTEN_KEEPALIVE Pairing_aggregate_pk_in_g1_6(Pairing* self,
|
|
const P1_Affine* pk, const P2_Affine* sig,
|
|
const byte* msg, size_t msg_len,
|
|
const byte* aug, size_t aug_len)
|
|
{ return self->aggregate(pk, sig, msg, msg_len, aug, aug_len); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['aggregate'] = Pairing.prototype.aggregate = /** @this{Object} */
|
|
function(pk, sig, msg, aug)
|
|
{ ensureCache.prepare();
|
|
const [_msg, msg_len] = ensureAny(msg);
|
|
const [_aug, aug_len] = ensureAny(aug);
|
|
if (pk instanceof P1_Affine && sig instanceof P2_Affine)
|
|
return _Pairing_aggregate_pk_in_g1_6(this.ptr, pk.ptr, sig.ptr, _msg, msg_len, _aug, aug_len);
|
|
else if (pk instanceof P2_Affine && sig instanceof P1_Affine)
|
|
return _Pairing_aggregate_pk_in_g2_6(this.ptr, pk.ptr, sig.ptr, _msg, msg_len, _aug, aug_len);
|
|
else
|
|
throw new Error(unsupported(pk, sig));
|
|
return -1;
|
|
};;
|
|
"""
|
|
p1_cpp += """
|
|
int EMSCRIPTEN_KEEPALIVE Pairing_mul_n_aggregate_pk_in_g1_8(Pairing* self,
|
|
const P1_Affine* pk, const P2_Affine* sig,
|
|
const byte* scalar, size_t nbits,
|
|
const byte* msg, size_t msg_len,
|
|
const byte* aug, size_t aug_len)
|
|
{ return self->mul_n_aggregate(pk, sig, scalar, nbits, msg, msg_len, aug, aug_len); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['mul_n_aggregate'] = Pairing.prototype.mul_n_aggregate = /** @this{Object} */
|
|
function(pk, sig, scalar, msg, aug)
|
|
{ if (typeof scalar === 'undefined' || scalar === null)
|
|
throw new Error("missing |scalar| argument");
|
|
ensureCache.prepare();
|
|
const [_scalar, len] = ensureAny(scalar);
|
|
const [_msg, msg_len] = ensureAny(msg);
|
|
const [_aug, aug_len] = ensureAny(aug);
|
|
if (pk instanceof P1_Affine && sig instanceof P2_Affine)
|
|
return _Pairing_mul_n_aggregate_pk_in_g1_8(this.ptr, pk.ptr, sig.ptr, _scalar, len*8, _msg, msg_len, _aug, aug_len);
|
|
else if (pk instanceof P2_Affine && sig instanceof P1_Affine)
|
|
return _Pairing_mul_n_aggregate_pk_in_g2_8(this.ptr, pk.ptr, sig.ptr, _scalar, len*8, _msg, msg_len, _aug, aug_len);
|
|
else
|
|
throw new Error(unsupported(pk, sig));
|
|
return -1;
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Pairing_commit_0(Pairing* self)
|
|
{ self->commit(); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['commit'] = Pairing.prototype.commit = /** @this{Object} */
|
|
function()
|
|
{ _Pairing_commit_0(this.ptr); };;
|
|
"""
|
|
common_cpp += """
|
|
size_t EMSCRIPTEN_KEEPALIVE Pairing_sizeof_0()
|
|
{ return blst_pairing_sizeof(); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['asArrayBuffer'] = Pairing.prototype.asArrayBuffer = /** @this{Object} */
|
|
function()
|
|
{ return HEAP8.buffer.slice(this.ptr, this.ptr + _Pairing_sizeof_0()); };;
|
|
"""
|
|
common_cpp += """
|
|
int EMSCRIPTEN_KEEPALIVE Pairing_merge_1(Pairing* self, const Pairing* ctx)
|
|
{ return self->merge(ctx); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['merge'] = Pairing.prototype.merge = /** @this{Object} */
|
|
function(ctx)
|
|
{ if (ctx instanceof Pairing)
|
|
return _Pairing_merge_1(this.ptr, ctx.ptr);
|
|
else if (ctx instanceof ArrayBuffer && ctx.byteLength == _Pairing_sizeof_0())
|
|
return _Pairing_merge_1(this.ptr, ensureAny(ctx)[0]);
|
|
throw new Error(unsupported(ctx));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
bool EMSCRIPTEN_KEEPALIVE Pairing_finalverify_1(const Pairing* self, const PT* sig)
|
|
{ return self->finalverify(sig); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['finalverify'] = Pairing.prototype.finalverify = /** @this{Object} */
|
|
function(sig)
|
|
{ if (typeof sig === 'undefined' || sig === null)
|
|
return !!(_Pairing_finalverify_1(this.ptr, 0));
|
|
else if (sig instanceof PT)
|
|
return !!(_Pairing_finalverify_1(this.ptr, sig.ptr));
|
|
else
|
|
throw new Error(unsupported(sig));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
void EMSCRIPTEN_KEEPALIVE Pairing_raw_aggregate_2(Pairing* self, const P2_Affine* q, const P1_Affine* p)
|
|
{ self->raw_aggregate(q, p); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['raw_aggregate'] = Pairing.prototype.raw_aggregate = /** @this{Object} */
|
|
function(q, p)
|
|
{ if (q instanceof P2_Affine && p instanceof P1_Affine)
|
|
_Pairing_raw_aggregate_2(this.ptr, q.ptr, p.ptr);
|
|
else
|
|
throw new Error(unsupported(q, p));
|
|
};;
|
|
"""
|
|
common_cpp += """
|
|
PT* EMSCRIPTEN_KEEPALIVE Pairing_as_fp12_0(Pairing* self)
|
|
{ return new PT(self->as_fp12()); }
|
|
"""
|
|
common_js += """
|
|
Pairing.prototype['as_fp12'] = Pairing.prototype.as_fp12 = /** @this{Object} */
|
|
function()
|
|
{ return wrapPointer(_Pairing_as_fp12_0(this.ptr), PT); };;
|
|
"""
|
|
|
|
|
|
blst_js = os.path.join(os.getcwd(), "blst.js") # output file
|
|
there = re.split(r'[/\\](?=[^/\\]*$)', sys.argv[0])
|
|
if len(there) > 1:
|
|
os.chdir(there[0])
|
|
|
|
|
|
def xchg_1vs2(matchobj):
|
|
if matchobj.group(2) == '1':
|
|
return matchobj.group(1) + '2'
|
|
else:
|
|
return matchobj.group(1) + '1'
|
|
|
|
|
|
fd = open("blst_bind.cpp", "w")
|
|
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
|
|
print("// DO NOT EDIT THIS FILE!!!", file=fd)
|
|
print("// The file is auto-generated by " + there[-1], file=fd)
|
|
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
|
|
print(common_cpp, file=fd)
|
|
print(p1_cpp, file=fd)
|
|
print(re.sub(r'((?<!f)[pgPG\*])([12])', xchg_1vs2, p1_cpp), file=fd)
|
|
print("}", file=fd) # close extern "C" {
|
|
fd.close()
|
|
|
|
fd = open("blst_bind.js", "w")
|
|
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
|
|
print("// DO NOT EDIT THIS FILE!!!", file=fd)
|
|
print("// The file is auto-generated by " + there[-1], file=fd)
|
|
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
|
|
print(common_js, file=fd)
|
|
print(p1_js, file=fd)
|
|
print(re.sub(r'((?<!f)[pgPG\*])([12])', xchg_1vs2, p1_js), file=fd)
|
|
fd.close()
|
|
|
|
subprocess.check_call([os.path.join(os.path.dirname(emcc), "tools", "webidl_binder"),
|
|
os.devnull, "null_bind"])
|
|
subprocess.check_call([emcc, "-I..", "-fexceptions", "-include", "stddef.h",
|
|
"-sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[$intArrayFromString]",
|
|
"-sEXPORTED_FUNCTIONS=[_malloc,_free]",
|
|
"null_bind.cpp", "--post-js", "null_bind.js",
|
|
"blst_bind.cpp", "--post-js", "blst_bind.js",
|
|
os.path.normpath("../../src/server.c"),
|
|
"-o", blst_js] +
|
|
sys.argv[1:]) # pass through flags, e.g. -O2 --closure 1
|
|
|
|
for opt in sys.argv[1:]:
|
|
if opt.find("EXPORT_NAME=") >= 0:
|
|
sys.exit(0)
|
|
|
|
# Rename 'Module' to 'blst' for smoother use in browser. This is done by
|
|
# finding the very 1st variable declaration, taking its name and replacing
|
|
# its occurrences with 'blst' through the whole script. [Yes, there is
|
|
# -sEXPORT_NAME=name, but it doesn't seem to work quite the way I expected.]
|
|
|
|
with open(blst_js, "r") as fd:
|
|
contents = fd.readlines()
|
|
|
|
replace = None
|
|
for i, line in enumerate(contents):
|
|
if replace is None:
|
|
match = re.search(r'\bvar\s+([A-Z_a-z][0-9A-Z_a-z]*)\b', line)
|
|
if match:
|
|
replace = re.compile(r'\b(?<!\$){}\b'.format(match.group(1)))
|
|
contents[i] = replace.sub('blst', line)
|
|
else:
|
|
contents[i] = replace.sub('blst', line)
|
|
|
|
with open(blst_js, "w") as fd:
|
|
fd.writelines(contents)
|