Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #198041

jacobi_symbol.py (was: Re: myrkraverk.c)

Date 2026-09-21 20:34 +0800
Subject jacobi_symbol.py (was: Re: myrkraverk.c)
Newsgroups comp.lang.python, sci.math, sci.crypt
References (2 earlier) <JbBrS.493032$a02.417651@fx11.ams4> <118mo9b$2i0j0$1@dont-email.me> <WjCrS.369387$G71.22768@fx17.ams4> <extension-20260919213739@ram.dialup.fu-berlin.de> <w9OrS.493051$a02.195416@fx11.ams4>
From Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid>
Organization Watcom Pro Ltd.
Message-ID <nnd$14d1509f$7d9dd275@76b9dc40c1eacecd> (permalink)

Cross-posted to 3 groups.

Show all headers | View raw


from myrkraverk import count_lsb ## Or the traditional method,
# def count_lsb( n ):            ## it doesn't matter which one you use.
#     return ( n & -n ).bit_length() - 1

## September 21, 2026.  Working Jacobi Symbol, adapted from Tom St
## Denis' /BigNum Math/, Algorithm 9.6, page 268, and the subsequent C
## code.  I believe Figure 9.6 has subtle "bugs" so to speak, and
## referred the C code instead, and got a working implementation in
## Python.

def jacobi( a, p ):
     if a == 0:        ## Handle the trivial cases.
         return 0
     if a == 1:
         return 1

     ## /Divide/ out the power of two.  Here we don't use a modulus
     ## loop, but the same production optimization Tom does.  The
     ## name a1 comes from Tom as a replacement for a'.
     k = count_lsb( a )
     a1 = a >> k

     ## In the following commentary, == means "congruence" as this is
     ## not a Unicode source.  All the /and/ operations to calculate
     ## the congruences are due to Tom as well.

     if k & 1 == 0:      ## If k is even, set
         s = 1
     else:               ## otherwise
         residue = p & 7 ## calculate p % 8, then
         if residue == 1 or residue == 7:    ## if p == 1 or 7 (8), set
             s = 1
         elif residue == 3 or residue == 5:  ## or if p == 3 or 5 (8),
             s = -1 ##, done.

     if p & 3 == 3 and a1 & 3 == 3: ## If p == 3 (4) /and/ a1 == 3 (4),
         s = -s ##, done.

     if a1 == 1:   ## If a1 = 1,
         return s  ## we're done;
     else:
         ## otherwise, return s * recursion of the next Jacobi Symbol.
         return s * jacobi( p % a1, a1 )

## I have checked the above function with the ten Cryptohack challenge
## numbers against the implementation in SymPy, and they are
## equivalent.  That's not a /proof of correctness/, but will do for
## now.


-- 
Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
I'm not from the Internet, I just work there. | via XS News
https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

( n & -n ).bit_length() - 1 ## Really? "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 01:56 +0800
  Re: ( n & -n ).bit_length() - 1 ## Really? ram@zedat.fu-berlin.de (Stefan Ram) - 2026-09-19 18:23 +0000
    Re: ( n & -n ).bit_length() - 1 ## Really? "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 03:15 +0800
      Re: ( n & -n ).bit_length() - 1 ## Really? Lane W <cactus_DAC@yahoo.com> - 2026-09-19 13:37 -0600
        Re: ( n & -n ).bit_length() - 1 ## Really? "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 04:32 +0800
          Re: ( n & -n ).bit_length() - 1 ## Really? ram@zedat.fu-berlin.de (Stefan Ram) - 2026-09-19 20:39 +0000
            Re: ( n & -n ).bit_length() - 1 ## Really? "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 04:56 +0800
            myrkraverk.c (was: Re: ( n & -n ).bit_length() - 1 ## Really?) "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 18:00 +0800
              Re: myrkraverk.c ram@zedat.fu-berlin.de (Stefan Ram) - 2026-09-20 12:25 +0000
                Re: myrkraverk.c "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 21:33 +0800
                Re: myrkraverk.c ram@zedat.fu-berlin.de (Stefan Ram) - 2026-09-20 13:48 +0000
                Re: myrkraverk.c "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 22:09 +0800
              jacobi_symbol.py (was: Re: myrkraverk.c) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-21 20:34 +0800
                Re: jacobi_symbol.py Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-22 15:20 +0800
                Re: jacobi_symbol.py Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-25 23:32 +0800
          Re: ( n & -n ).bit_length() - 1 ## Really? "Johann \"Myrkraverk\" Oskarsson" <johann@myrkraverk.invalid> - 2026-09-20 04:52 +0800
  Re: ( n & -n ).bit_length() - 1 ## Really? Paul Rubin <no.email@nospam.invalid> - 2026-09-19 14:50 -0700

csiph-web