<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Hi Jesper, Hanfei,</div><div><br></div><div><div>For the purpose in cryptographical applications this is not a problem, where in practivce only positive number are considered (actually elements from a group Z_p).</div></div><div><br></div><div>Of course one can debate whether Erlang should faithfully conserve the negative sign between libraries. But, as said before, for the crypto applications of mod_exp, it doesn't matter.</div><div><br></div><div><br></div><div>kr</div><div><br></div><div><br></div><div>Twan.</div><div><br></div><div><br></div><div><br></div><div>I went into the source code (see below) and the following happens:</div><div><br></div><div>0. The OpenSSL Big Number representation is a structure in which whether a number is negative is a separate flag in the structure:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: #b80ca1">struct</span> bignum_st</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">      </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">    </span>BN_ULONG *d;<span class="Apple-tab-span" style="white-space:pre">        </span></span>/* Pointer to an array of 'BN_BITS2' bit chunks. */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">     </span></span><span style="color: #b80ca1">int</span><span style="color: #000000"> top;<span class="Apple-tab-span" style="white-space:pre">        </span></span>/* Index of last used d +1. */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">  </span></span>/* The next are internal book keeping for bn_expand. */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b80ca1">int</span><span style="color: #000000"> dmax;<span class="Apple-tab-span" style="white-space:pre">       </span></span>/* Size of the d array. */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">      </span></span><span style="color: #b80ca1">int</span><span style="color: #000000"> neg;<span class="Apple-tab-span" style="white-space:pre">        </span></span>/* one if the number is negative */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">  </span><span style="color: #b80ca1">int</span> flags;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">      </span>};</div></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: #b80ca1">typedef</span> <span style="color: #b80ca1">struct</span> bignum_st BIGNUM;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><div style="font-family: Helvetica; font-size: medium; ">From the openSSL bn.h:</div><div style="font-family: Helvetica; font-size: medium; "><br></div><div style="font-family: Helvetica; font-size: medium; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); ">/** BN_set_negative sets sign of a BIGNUM</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> * \param  b  pointer to the BIGNUM object</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise </div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: rgb(184, 12, 161); ">void</span><span class="Apple-tab-span" style="white-space: pre; ">  </span>BN_set_negative(BIGNUM *b, <span style="color: rgb(184, 12, 161); ">int</span> n);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); ">/** BN_is_negative returns 1 if the BIGNUM is negative</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> * \param  a  pointer to the BIGNUM object</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> * \return 1 if a < 0 and 0 otherwise</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "> */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(118, 72, 45); ">#define BN_is_negative(a) ((a)->neg != <span style="color: rgb(61, 0, 214); ">0</span>)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(118, 72, 45); "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(118, 72, 45); "><br></div></div></div></div><div>1. The conversion of Erlang "big number" to openSSL "big numbers" ignores whether the binary big number representation of Erlang signifies a negative number:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: #b80ca1">static</span> <span style="color: #b80ca1">int</span> get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    ErlNifBinary bin;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">int</span> sz;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">if</span> (!enif_inspect_binary(env,term,&bin)) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>return<span style="color: #000000"> </span><span style="color: #3d00d6">0</span><span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    ERL_VALGRIND_ASSERT_MEM_DEFINED(bin.data, bin.size);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    sz = bin.size - <span style="color: #3d00d6">4</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">if</span> (sz < <span style="color: #3d00d6">0</span> || get_int32(bin.data) != sz) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">     </span></span>return<span style="color: #000000"> </span><span style="color: #3d00d6">0</span><span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    *bnp = BN_bin2bn(bin.data+<span style="color: #3d00d6">4</span>, sz, <span style="color: #b80ca1">NULL</span>);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">return</span> <span style="color: #3d00d6">1</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">}</div></div><div><br></div><div><br></div><div>2. The reverse conversion when the openSSL function BN_mod_exp has computed its result, the conversion from the openSSL representation to the Erlang representation ignores again any negative results.</div><div><br></div><div><br></div><div>From Erlang: crypto.c</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: #b80ca1">static</span> ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, <span style="color: #b80ca1">int</span> argc, <span style="color: #b80ca1">const</span> ERL_NIF_TERM argv[])</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: #000000">{</span>/* (Base,Exponent,Modulo) */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BIGNUM *bn_base=<span style="color: #b80ca1">NULL</span>, *bn_exponent=<span style="color: #b80ca1">NULL</span>, *bn_modulo, *bn_result;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_CTX *bn_ctx;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: #000000">    </span>unsigned<span style="color: #000000"> </span>char<span style="color: #000000">* ptr;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">unsigned</span> dlen;      </div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    ERL_NIF_TERM ret;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; min-height: 13px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">if</span> (!get_bn_from_mpint(env, argv[<span style="color: #3d00d6">0</span>], &bn_base)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">       </span>|| !get_bn_from_mpint(env, argv[<span style="color: #3d00d6">1</span>], &bn_exponent)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">   </span>|| !get_bn_from_mpint(env, argv[<span style="color: #3d00d6">2</span>], &bn_modulo)) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; min-height: 13px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">    </span><span style="color: #b80ca1">if</span> (bn_base) BN_free(bn_base);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">  </span><span style="color: #b80ca1">if</span> (bn_exponent) BN_free(bn_exponent);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">  </span><span style="color: #b80ca1">return</span> enif_make_badarg(env);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    bn_result = BN_new();</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    bn_ctx = BN_CTX_new();</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_mod_exp(bn_result, bn_base, bn_exponent, bn_modulo, bn_ctx);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    dlen = BN_num_bytes(bn_result);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    ptr = enif_make_new_binary(env, dlen+<span style="color: #3d00d6">4</span>, &ret);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    put_int32(ptr, dlen);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_bn2bin(bn_result, ptr+<span style="color: #3d00d6">4</span>);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_free(bn_result);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_CTX_free(bn_ctx);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_free(bn_modulo);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_free(bn_exponent);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    BN_free(bn_base);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">    <span style="color: #b80ca1">return</span> ret;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">}</div></div><div><br></div><div><div>From: openSSL: bn_lib.h:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">BIGNUM *BN_bin2bn(<span style="color: rgb(184, 12, 161); ">const</span> <span style="color: rgb(184, 12, 161); ">unsigned</span> <span style="color: rgb(184, 12, 161); ">char</span> *s, <span style="color: rgb(184, 12, 161); ">int</span> len, BIGNUM *ret)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">  </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: rgb(0, 0, 0); "><span class="Apple-tab-span" style="white-space: pre; ">        </span></span>unsigned<span style="color: rgb(0, 0, 0); "> </span>int<span style="color: rgb(0, 0, 0); "> i,m;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: rgb(0, 0, 0); "><span class="Apple-tab-span" style="white-space: pre; ">       </span></span>unsigned<span style="color: rgb(0, 0, 0); "> </span>int<span style="color: rgb(0, 0, 0); "> n;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">       </span>BN_ULONG l;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">    </span>BIGNUM  *bn = <span style="color: rgb(184, 12, 161); ">NULL</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; min-height: 13px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; "> </span><span style="color: rgb(184, 12, 161); ">if</span> (ret == <span style="color: rgb(184, 12, 161); ">NULL</span>)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">         </span>ret = bn = BN_new();</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: rgb(0, 0, 0); "><span class="Apple-tab-span" style="white-space: pre; ">     </span></span>if<span style="color: rgb(0, 0, 0); "> (ret == </span>NULL<span style="color: rgb(0, 0, 0); ">) </span>return<span style="color: rgb(0, 0, 0); ">(</span>NULL<span style="color: rgb(0, 0, 0); ">);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; "> </span>bn_check_top(ret);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">     </span>l=<span style="color: rgb(61, 0, 214); ">0</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">       </span>n=len;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; "> </span><span style="color: rgb(184, 12, 161); ">if</span> (n == <span style="color: rgb(61, 0, 214); ">0</span>)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">              </span>ret->top=<span style="color: rgb(61, 0, 214); ">0</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">             </span><span style="color: rgb(184, 12, 161); ">return</span>(ret);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">             </span>}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">      </span>i=((n-<span style="color: rgb(61, 0, 214); ">1</span>)/BN_BYTES)+<span style="color: rgb(61, 0, 214); ">1</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">  </span>m=((n-<span style="color: rgb(61, 0, 214); ">1</span>)%(BN_BYTES));</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">      </span><span style="color: rgb(184, 12, 161); ">if</span> (bn_wexpand(ret, (<span style="color: rgb(184, 12, 161); ">int</span>)i) == <span style="color: rgb(184, 12, 161); ">NULL</span>)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">               </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">              </span><span style="color: rgb(184, 12, 161); ">if</span> (bn) BN_free(bn);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: rgb(0, 0, 0); "><span class="Apple-tab-span" style="white-space: pre; ">          </span></span>return<span style="color: rgb(0, 0, 0); "> </span>NULL<span style="color: rgb(0, 0, 0); ">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">               </span>}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">      </span>ret->top=i;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; "> </span>ret->neg=<span style="color: rgb(61, 0, 214); ">0</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">     </span><span style="color: rgb(184, 12, 161); ">while</span> (n--)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">         </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">              </span>l=(l<<<span style="color: rgb(61, 0, 214); ">8L</span>)| *(s++);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">           </span><span style="color: rgb(184, 12, 161); ">if</span> (m-- == <span style="color: rgb(61, 0, 214); ">0</span>)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                      </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                      </span>ret->d[--i]=l;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                      </span>l=<span style="color: rgb(61, 0, 214); ">0</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                       </span>m=BN_BYTES-<span style="color: rgb(61, 0, 214); ">1</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">                      </span>}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">              </span>}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span style="color: rgb(0, 0, 0); "><span class="Apple-tab-span" style="white-space: pre; ">  </span></span>/* need to call this due to clear byte at top if avoiding</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); "><span class="Apple-tab-span" style="white-space: pre; "> </span> * having the top bit set (-ve number) */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; "> </span>bn_correct_top(ret);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">   </span><span style="color: rgb(184, 12, 161); ">return</span>(ret);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space: pre; ">     </span>}</div></div></div><div><br></div><div><font class="Apple-style-span" face="Menlo" size="3"><span class="Apple-style-span" style="font-size: 11px;"><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></span></font></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(0, 135, 12); ">/* ignore negative */</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span style="color: #b80ca1">int</span> BN_bn2bin(<span style="color: #b80ca1">const</span> BIGNUM *a, <span style="color: #b80ca1">unsigned</span> <span style="color: #b80ca1">char</span> *to)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">     </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b80ca1">int</span> n,i;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">        </span>BN_ULONG l;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; min-height: 13px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>bn_check_top(a);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">  </span>n=i=BN_num_bytes(a);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">      </span><span style="color: #b80ca1">while</span> (i--)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">             </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">         </span>l=a->d[i/BN_BYTES];</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">            </span>*(to++)=(<span style="color: #b80ca1">unsigned</span> <span style="color: #b80ca1">char</span>)(l>>(<span style="color: #3d00d6">8</span>*(i%BN_BYTES)))&<span style="color: #3d00d6">0xff</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(184, 12, 161); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">  </span></span>return<span style="color: #000000">(n);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>}</div></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><br></div><div><br></div><div><br></div><div><br></div><br><div><div>On 30 mei 2011, at 08:39, Jesper Pettersson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Writing a small example in C using the bignum library in openssl (used by the Erlang crypto driver) shows that the result there is 1 as well.<div><br></div><div><div>#include <stdio.h></div><div>#include <openssl/crypto.h></div>
<div>#include <openssl/bn.h></div><div><br></div><div>int main(int argc, char *argv[])</div><div>{</div><div>        static const char b[] = "-2";</div><div>        static const char e[] = "3";</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>static const char m[] = "3";</div><div><br></div><div>        BIGNUM *bnb = NULL;</div><div>        BIGNUM *bne = NULL;</div><div>        BIGNUM *bnm = NULL;</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>BIGNUM *res = BN_new();</div><div><br></div><div>        BN_CTX *ctx = BN_CTX_new();</div><div><br></div><div>        BN_dec2bn(&bnb, b); /* convert the string to BIGNUM */</div>
<div>        BN_dec2bn(&bne, e);</div><div>        BN_dec2bn(&bnm, m);</div><div><br></div><div>        BN_mod_exp(res, bnb, bne, bnm, ctx); </div><div><br></div><div>        char *result_str = BN_bn2dec(res); /* convert the res BIGNUM to string */</div>
<div><br></div><div>        printf("%s\n", result_str);</div><div><br></div><div>        OPENSSL_free(result_str);</div><div><br></div><div>        BN_free(bnb);</div><div>        BN_free(bne);</div><div>        BN_free(bnm);</div>
<div>        BN_CTX_free(ctx);</div><div><br></div><div>        return 0;</div><div>}</div><div><br></div><div><div>$ gcc -o bn -lcrypto bn.c</div><div>$ ./bn</div><div>1</div></div><div><br></div><div>/Jesper Pettersson</div>
<div>Klarna AB</div><div><br></div><div class="gmail_quote">On Sat, May 28, 2011 at 8:22 PM, Hanfei Shen <span dir="ltr"><<a href="mailto:qqshfox@gmail.com">qqshfox@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi all,<br><br>As the doc says:<br><br>mod_exp(N, P, M) -> Result<br><br>Types:<br>N, P, M, Result = Mpint<br>Mpint = binary()<br><br>This function performs the exponentiation N ^ P mod M, using the crypto library.<br>
<br>
Now, assume: N = -2, P = 3, M = 3<br>Then: N ^ P mod M = (-2) ^ 3 mod 3<br>                  = (-8) mod 3<br>                  = (-3) * 3 + 1<br>               or = (-3) * 2 + (-2)<br>So: the remainder should be 1 or -2<br>

(Remainder, From Wikipedia, <a href="http://en.wikipedia.org/wiki/Remainder" target="_blank">http://en.wikipedia.org/wiki/Remainder</a>)<br><br>But I got a TWO from crypto:mod_exp/3... Is there some wrong...?<br>And I did more tests with erlang, python and ruby.<br>

The result:<br><br>Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]<br><br>Eshell V5.8.3  (abort with ^G)<br>1> crypto:mod_exp(-2, 3, 3).<br>2<br>2> crypto:mod_exp(2, 3, 3).<br>

2<br>3> crypto:mod_exp(-2, 3, -3).<br>1<br>4> crypto:mod_exp(2, 3, -3).<br>8<br><br>Python 2.7.1 (r271:86832, Mar 25 2011, 15:07:46)<br><br>In [1]: pow(-2, 3, 3)<br>Out[1]: 1<br><br>In [2]: pow(2, 3, 3)<br>Out[2]: 2<br>

<br>In [3]: pow(-2, 3, -3)<br>Out[3]: -2<br><br>In [4]: pow(2, 3, -3)<br>Out[4]: -1<br><br>Welcome to IRB. You are using ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]. Have fun ;)<br>irb(main):001:0> (-2) ** 3 % 3<br>

1<br>irb(main):002:0> 2 ** 3 % 3<br>2<br>irb(main):003:0> (-2) ** 3 % (-3)<br>-2<br>irb(main):004:0> 2 ** 3 % (-3)<br>-1<br><br><br>Regards,<br><font color="#888888">Hanfei<br>
</font><br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Jesper Pettersson<br><br>Klarna AB<br>Norra Stationsgatan 61<br>113 43 Stockholm, Sweden<br>Tel:         +46 8 - 120 120 00<br>Mob:       +46 70 - 001 27 25<br>Fax:        +46 8 - 120 120 99<br>
E-mail:     <a href="mailto:jesper.pettersson@klarna.com">jesper.pettersson@klarna.com</a><br>Web:        <a href="http://www.klarna.com/">www.klarna.com</a><br>
</div>
_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>http://erlang.org/mailman/listinfo/erlang-questions<br></blockquote></div><br></body></html>