Reject text: IC0503: Canister trapped explicitly: bigint function error

I’m attempting (in Motoko) to decompress the compressed public key that is returned from the ecdsa_public_key function within the management canister interface. As far as I know, this is a necessary step in order to be able to authenticate an HTTP request with an ECDSA signature.

To achieve this decompression, I’m using the method referenced by @LightningLad91 which can be found here.

This method requires me to perform exponentiation in modulo p : (a**b) % p

where a’s value is 77 digits long, b’s value is 77 digits long and p’s value is 78 digits long.
as far as I know, theres no library available in motoko that would allow me to perform this exponentiation in a manner that is Space efficient. The only way (that I’m aware of) for exponentiating in modulo p is to perform the exponentiation and then take the remainder modulo p of the result of said exponentiation.

the issue with this approach is that the result of the exponentiation of such large numbers results in a number too large to fit within the canister’s storage and its causing the canister to trap.

My question is, are there any library functions that would allow me to be able to perform this exponentiation in modulo p in a space efficient way that won’t cause the canister to blow up?

also, is there another way to decompress the public the ecdsa_public_key?

also, is it even necessary to decompress the ecdsa_public_key? I don’t suppose it would be possible to perform the signature authentication using the compressed key, would it?

2 Likes

I found some python code that performs exponentiation in modulo p efficiently. I’m putting it here for the next person who needs it when the time comes:

def pow_mod(x, y, z):
    "Calculate (x ** y) % z efficiently."
    number = 1
    while y:
        if y & 1:
            number = number * x % z
        y >>= 1
        x = x * x % z
    return number
2 Likes

Here is how one can perform exponentiation in modulo P where the base, exponent, and modulus are all ridiculously large natural numbers, without encountering the bigint function error, in the motoko langauge:

public func pow_mod(base: Nat, exponent: Nat, modulus: Nat ) : Nat {
    var result: Nat = 1;
    var base_ = base;
    var exponent_ = exponent;

    base_ := base_ % modulus;
    while (exponent_ > 0){
      if(exponent_ % 2 == 1) result := (result * base_) % modulus;
      exponent_ := exponent_ / 2;
      base_ := (base_ * base_) % modulus
    };
    return result;
  };
1 Like

Awesome, thanks @Jesse!