how can I compute subaddress Sa(a,i) where a is the account index and
i is the subaddress index within the account?
You're right, it is not fully explained in either of those links.
Take a look at get_subaddress_spend_public_keys and get_subaddress_secret_key in the source code.
You'll see in the code that subaddress_index is a struct containing "major" and "minor", where major means the account index and minor means the subaddress index within that account. You'll also see the in second link that the string "SubAddr" is added into the mix.
Bringing it all together:
m = Hs("SubAddr" || a || account_index || subaddress_index_within_account)
Where a
is a 32 byte scalar (the private view key), and account_index
and subaddress_index_within_account
are both 32 bit little endian unsigned integers.
Note that "SubAddr" needs to be a null terminated string, i.e. will be 8 bytes and not 7.
Finally, to get the wallet address for a subaddress, you need to follow the usual base58 procedure (which involves adding an identifier for the type of wallet address and adding a checksum) on the public view and spend keys (C, D), calculated as:
D = B + m*G
C = a*D
Also note that there is a special case, where the first subaddress of the first account is not calculated using the formula above, and instead is simply the ordinary main wallet address (A, B).
Edit: See an example Javascript implementation of a subaddress generator here: https://github.com/knaccc/subaddress-js