diff options
| author | J08nY | 2020-02-20 20:41:29 +0100 |
|---|---|---|
| committer | J08nY | 2020-02-20 20:41:29 +0100 |
| commit | 3892d994470b181f950703fabf719a9c963d1c20 (patch) | |
| tree | fc1c7e68fc6334a7f89fd69eab00a830fb58f275 /pyecsca/codegen | |
| parent | 92cb16e8103da998aa1bf226d24ef6771a92c5d5 (diff) | |
| download | pyecsca-codegen-3892d994470b181f950703fabf719a9c963d1c20.tar.gz pyecsca-codegen-3892d994470b181f950703fabf719a9c963d1c20.tar.zst pyecsca-codegen-3892d994470b181f950703fabf719a9c963d1c20.zip | |
Add full implementation tests.
Diffstat (limited to 'pyecsca/codegen')
| -rw-r--r-- | pyecsca/codegen/asn1/asn1.c | 9 | ||||
| -rw-r--r-- | pyecsca/codegen/builder.py | 28 | ||||
| -rw-r--r-- | pyecsca/codegen/client.py | 32 | ||||
| -rw-r--r-- | pyecsca/codegen/templates/main.c | 7 | ||||
| -rw-r--r-- | pyecsca/codegen/templates/mult_ltr.c | 4 | ||||
| -rw-r--r-- | pyecsca/codegen/templates/mult_rtl.c | 4 |
6 files changed, 48 insertions, 36 deletions
diff --git a/pyecsca/codegen/asn1/asn1.c b/pyecsca/codegen/asn1/asn1.c index 3fd1f5f..13bfa5c 100644 --- a/pyecsca/codegen/asn1/asn1.c +++ b/pyecsca/codegen/asn1/asn1.c @@ -7,8 +7,8 @@ uint8_t *asn1_der_encode(const bn_t *r, const bn_t *s, size_t *result_len) { uint8_t s_len = (uint8_t) bn_to_bin_size(s); // Pad with one zero byte in case most-significant bit of top byte is one. - uint8_t r_length = r_len + (bn_get_bit(r, r_len * 8) ? 1 : 0); - uint8_t s_length = s_len + (bn_get_bit(s, s_len * 8) ? 1 : 0); + uint8_t r_length = r_len + (bn_get_bit(r, (r_len * 8) - 1) ? 1 : 0); + uint8_t s_length = s_len + (bn_get_bit(s, (s_len * 8) - 1) ? 1 : 0); // R and S are < 128 bytes, so 1 byte tag + 1 byte len + len bytes value size_t seq_value_len = 2 + r_length + 2 + s_length; @@ -29,6 +29,7 @@ uint8_t *asn1_der_encode(const bn_t *r, const bn_t *s, size_t *result_len) { whole_len += 1; uint8_t *data = malloc(whole_len); + *result_len = whole_len; size_t i = 0; data[i++] = 0x30; // SEQUENCE if (seq_value_len < 128) { @@ -41,14 +42,14 @@ uint8_t *asn1_der_encode(const bn_t *r, const bn_t *s, size_t *result_len) { } data[i++] = 0x02; //INTEGER data[i++] = r_length; - if (bn_get_bit(r, r_len * 8)) { + if (bn_get_bit(r, (r_len * 8) - 1)) { data[i++] = 0; } bn_to_bin(r, data + i); i += r_len; data[i++] = 0x02; //INTEGER data[i++] = s_length; - if (bn_get_bit(s, s_len * 8)) { + if (bn_get_bit(s, (s_len * 8) - 1)) { data[i++] = 0; } bn_to_bin(s, data + i); diff --git a/pyecsca/codegen/builder.py b/pyecsca/codegen/builder.py index b9f9708..bf8e6be 100644 --- a/pyecsca/codegen/builder.py +++ b/pyecsca/codegen/builder.py @@ -73,16 +73,6 @@ def get_multiplier(ctx: click.Context, param, value: Optional[str]) -> Optional[ return mult -def get_ecdsa(ctx: click.Context, param, value: bool) -> bool: - if not value: - return False - ctx.ensure_object(dict) - formulas = ctx.obj["formulas"] - if not any(isinstance(formula, AdditionFormula) for formula in formulas): - raise click.BadParameter("ECDSA needs an addition formula. None was supplied.") - return value - - @click.group(context_settings={"help_option_names": ["-h", "--help"]}) @click.version_option() @public @@ -118,12 +108,15 @@ def main(): type=click.Choice(Reduction.names()), callback=wrap_enum(Reduction), help="Modular reduction algorithm to use.") -@click.option("--keygen/--no-keygen", help="Whether to enable keygen.", is_flag=True, default=True, show_default=True) -@click.option("--ecdh/--no-ecdh", help="Whether to enable ECDH.", is_flag=True, default=True, show_default=True) +@click.option("--keygen/--no-keygen", help="Whether to enable keygen.", is_flag=True, default=True, + show_default=True) +@click.option("--ecdh/--no-ecdh", help="Whether to enable ECDH.", is_flag=True, default=True, + show_default=True) @click.option("--ecdsa/--no-ecdsa", help="Whether to enable ECDSA.", is_flag=True, default=True, - callback=get_ecdsa, show_default=True) + show_default=True) @click.option("--strip", help="Whether to strip the binary or not.", is_flag=True) -@click.option("--remove/--no-remove", help="Whether to remove the dir.", is_flag=True, default=True, show_default=True) +@click.option("--remove/--no-remove", help="Whether to remove the dir.", is_flag=True, default=True, + show_default=True) @click.option("-v", "--verbose", count=True) @click.argument("model", required=True, type=click.Choice(["shortw", "montgom", "edwards", "twisted"]), @@ -135,8 +128,9 @@ def main(): @click.argument("scalarmult", required=True, callback=get_multiplier) @click.argument("outdir") +@click.pass_context @public -def build_impl(platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, strip, remove, +def build_impl(ctx, platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, strip, remove, verbose, model, coords, formulas, scalarmult, outdir): """This command builds an ECC implementation. @@ -147,6 +141,10 @@ def build_impl(platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, strip, SCALARMULT: The scalar multiplication algorithm to use. OUTDIR: The output directory for files with the built impl. """ + ctx.ensure_object(dict) + formulas = ctx.obj["formulas"] + if ecdsa and not any(isinstance(formula, AdditionFormula) for formula in formulas): + raise click.BadParameter("ECDSA needs an addition formula. None was supplied.") config = DeviceConfiguration(model, coords, formulas, scalarmult, hash, rand, mul, sqr, red, platform, keygen, ecdh, ecdsa) diff --git a/pyecsca/codegen/client.py b/pyecsca/codegen/client.py index 197c703..cd4cff7 100644 --- a/pyecsca/codegen/client.py +++ b/pyecsca/codegen/client.py @@ -68,16 +68,16 @@ def cmd_init_prng(seed: bytes) -> str: @public -def cmd_set_params(group: DomainParameters) -> str: +def cmd_set_params(params: DomainParameters) -> str: data = { - "p": encode_scalar(group.curve.prime), - "n": encode_scalar(group.order), - "h": encode_scalar(group.cofactor) + "p": encode_scalar(params.curve.prime), + "n": encode_scalar(params.order), + "h": encode_scalar(params.cofactor) } - for param, value in group.curve.parameters.items(): + for param, value in params.curve.parameters.items(): data[param] = encode_scalar(value) - data["g"] = encode_point(group.generator.to_affine()) - data["i"] = encode_point(group.neutral) + data["g"] = encode_point(params.generator.to_affine()) + data["i"] = encode_point(params.curve.neutral) return "c" + hexlify(encode_data(None, data)).decode() @@ -113,7 +113,7 @@ def cmd_ecdsa_sign(data: bytes) -> str: @public def cmd_ecdsa_verify(data: bytes, sig: bytes) -> str: - return "v" + hexlify(encode_data(None, {"d": data, "s": sig})).decode() + return "r" + hexlify(encode_data(None, {"d": data, "s": sig})).decode() @public @@ -173,7 +173,7 @@ class ImplTarget(SerialTarget): def scalar_mult(self, scalar: int) -> Point: self.write(cmd_scalar_mult(scalar).encode()) result = self.read(1)[1:-1] - plen = (self.params.curve.prime + 7) // 8 + plen = ((self.params.curve.prime.bit_length() + 7) // 8) * 2 self.read(1) params = {var: Mod(int(result[i * plen:(i + 1) * plen], 16), self.params.curve.prime) for i, var in enumerate(self.coords.variables)} @@ -209,10 +209,12 @@ class ImplTarget(SerialTarget): class BinaryTarget(ImplTarget): binary: str process: Optional[Popen] + debug_output: bool - def __init__(self, binary: str, model: CurveModel, coords: CoordinateModel): + def __init__(self, binary: str, model: CurveModel, coords: CoordinateModel, debug_output: bool = False): super().__init__(model, coords) self.binary = binary + self.debug_output = debug_output def connect(self): self.process = Popen([self.binary], stdin=subprocess.PIPE, stdout=subprocess.PIPE, @@ -221,20 +223,26 @@ class BinaryTarget(ImplTarget): def write(self, data: bytes): if self.process is None: raise ValueError + if self.debug_output: + print(">>", data.decode()) self.process.stdin.write(data.decode() + "\n") self.process.stdin.flush() def read(self, timeout: int) -> bytes: if self.process is None: raise ValueError - return self.process.stdout.readline().encode() + read = self.process.stdout.readline().encode() + if self.debug_output: + print("<<", read.decode(), end="") + return read def disconnect(self): if self.process is None: return self.process.stdin.close() self.process.stdout.close() - self.process.kill() + self.process.terminate() + self.process.wait() @click.group(context_settings={"help_option_names": ["-h", "--help"]}) diff --git a/pyecsca/codegen/templates/main.c b/pyecsca/codegen/templates/main.c index ae36bfd..b0f81f1 100644 --- a/pyecsca/codegen/templates/main.c +++ b/pyecsca/codegen/templates/main.c @@ -325,12 +325,17 @@ static uint8_t cmd_ecdsa_sign(uint8_t *data, uint16_t len) { bn_t r; bn_init(&r); point_to_affine(p, curve, &r, NULL); bn_mod(&r, &curve->n, &r); + // r = ([k]G).x mod n bn_t s; bn_init(&s); bn_copy(&privkey, &s); + // s = x bn_mod_mul(&s, &r, &curve->n, &s); + // s = rx mod n bn_mod_add(&s, &h, &curve->n, &s); + // s = rx + H(m) mod n bn_mod_div(&s, &k, &curve->n, &s); + // s = k^(-1)*(rx + H(m)) mod n size_t result_len = 0; uint8_t *result = asn1_der_encode(&r, &s, &result_len); @@ -444,7 +449,7 @@ int main(void) { {%- endif %} {%- if ecdsa %} simpleserial_addcmd('a', MAX_SS_LEN, cmd_ecdsa_sign); - simpleserial_addcmd('v', MAX_SS_LEN, cmd_ecdsa_verify); + simpleserial_addcmd('r', MAX_SS_LEN, cmd_ecdsa_verify); {%- endif %} simpleserial_addcmd('d', MAX_SS_LEN, cmd_debug); diff --git a/pyecsca/codegen/templates/mult_ltr.c b/pyecsca/codegen/templates/mult_ltr.c index dbd4704..5b08b80 100644 --- a/pyecsca/codegen/templates/mult_ltr.c +++ b/pyecsca/codegen/templates/mult_ltr.c @@ -19,10 +19,10 @@ void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) { for (int i = nbits; i >= 0; i--) { point_dbl(r, curve, r); if (bn_get_bit(scalar, i) == 1) { - point_add(q, r, curve, r); + point_add(r, q, curve, r); } else { {%- if scalarmult.always %} - point_add(q, r, curve, dummy); + point_add(r, q, curve, dummy); {%- endif %} } } diff --git a/pyecsca/codegen/templates/mult_rtl.c b/pyecsca/codegen/templates/mult_rtl.c index 01d42a5..ba40a66 100644 --- a/pyecsca/codegen/templates/mult_rtl.c +++ b/pyecsca/codegen/templates/mult_rtl.c @@ -14,10 +14,10 @@ void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) { while (!bn_is_0(©)) { if (bn_get_bit(©, 0) == 1) { - point_add(q, r, curve, r); + point_add(r, q, curve, r); } else { {%- if scalarmult.always %} - point_add(q, r, curve, dummy); + point_add(r, q, curve, dummy); {%- endif %} } point_dbl(q, curve, q); |
