0

Expected result:

mnemonic: "sample split bamboo west visual approve brain fox arch impact relief smile" --scheme "ed25519" Secret phrase: sample split bamboo west visual approve brain fox arch impact relief smile

Network ID: substrate

Secret seed:
0x9fa1ab1d37025d8c3cd596ecbf50435572eeaeb1785a0c9ed2b22afa4c378d6a

Public key (hex): 0x10b22ebe89b321370bee8d39d5c5d411daf1e8fc91c9d1534044590f1f966ebc

Account ID:
0x10b22ebe89b321370bee8d39d5c5d411daf1e8fc91c9d1534044590f1f966ebc

Public key (SS58): 5CSbZ7wG456oty4WoiX6a1J88VUbrCXLhrKVJ9q95BsYH4TZ

SS58 Address: 5CSbZ7wG456oty4WoiX6a1J88VUbrCXLhrKVJ9q95BsYH4TZ

Please guide, how to derive substrate public key in c?

Also, while I am trying to derive the account address from the know public key through c implementation:
https://github.com/Zondax/ledger-polkadot/blob/9d06c78f7ec1c096d2bccae863e932fbddde5a37/app/src/crypto_helper.c

  ...
  hex_string_to_byte_array(
  "10b22ebe89b321370bee8d39d5c5d411daf1e8fc91c9d1534044590f1f966ebc",
  64, pubkey);
  u8ToHexStr("public key manual", pubkey, PK_LEN_25519);

  // Get Account

  printf("\n\n");

  char address[100] = "";
  size_t address_size = sizeof(address);

  // get address func
  uint16_t outlen = crypto_SS58EncodePubkey(address, &address_size, 0, pubkey);
...

  int ss58hash(const unsigned char *in,
                 unsigned int inLen,
                 unsigned char *out,
                 unsigned int outLen) {
      blake2b_state s;
      blake2b_Init(&s, 64);
      blake2b_Update(&s, SS58_BLAKE_PREFIX, SS58_BLAKE_PREFIX_LEN);
      blake2b_Update(&s, in, inLen);
      blake2b_Final(&s, out, outLen);
      return 0;
    }
    
    uint16_t crypto_SS58EncodePubkey(char *buffer,
                                     uint16_t buffer_len,
                                     uint16_t addressType,
                                     const uint8_t *pubkey) {
      // based on https://docs.substrate.io/v3/advanced/ss58/
      if (buffer == NULL || buffer_len < SS58_ADDRESS_MAX_LEN) {
        return 0;
      }
  if (pubkey == NULL) {
    return 0;
  }

  uint8_t hash[64] = {0};
  uint8_t unencoded[36] = {0};
  
  uint8_t prefixSize;
  if (addressType > 16383) {
    prefixSize = 0;
  }

  if (addressType > 63) {
    unencoded[0] = 0x40 | ((addressType >> 2) & 0x3F);
    unencoded[1] = ((addressType & 0x3) << 6) + ((addressType >> 8) & 0x3F);
    prefixSize = 2;
  } else {
    unencoded[0] = addressType & 0x3F;    // address type
    prefixSize = 1;
  }

  if (prefixSize == 0) {
    return 0;
  }

  memcpy(unencoded + prefixSize, pubkey, 32);    // account id
  u8ToHexStr("unencoded p", unencoded, 36);
  if (ss58hash((uint8_t *)unencoded, 32 + prefixSize, hash, 64) != 0) {
    memzero(unencoded, sizeof(unencoded));
    return 0;
  }
  unencoded[32 + prefixSize] = hash[0];
  unencoded[33 + prefixSize] = hash[1];

  u8ToHexStr("hash", hash, 64);
  u8ToHexStr("unencoded", unencoded, 36);

  char unencoded_str[36 * 2 + 1];
  u8ToHexStrr("unencoded str", unencoded, 36, unencoded_str);

  size_t outLen = buffer_len;
  if (b58enc(buffer, &buffer_len, unencoded_str, 34 + prefixSize) != true) {
    memzero(unencoded, sizeof(unencoded));
    return 0;
  }

  return outLen;
}

Getting following result:

public key: 0x10b22ebe89b321370bee8d39d5c5d411daf1e8fc91c9d1534044590f1f966ebc

hash: 0xf0a43f1e82a4cfb3fbf14a52a5b1fb9ee3467a752440ced68cc017af78121c73f1acb7c967de099503273c71ee720d420d5e028671003ddc7b3f01fd90d7dab2

unencoded str : 0x0010b22ebe89b321370bee8d39d5c5d411daf1e8fc91c9d1534044590f1f966ebcf0a400

address: 5osrKSRC5QMK6YDGTG7tBd2r7bxVp7148MKdejoeQRSKabF9

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.